/*
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef COBALT_DOM_TYPED_ARRAY_H_
#define COBALT_DOM_TYPED_ARRAY_H_

#include "base/logging.h"
#include "base/stringprintf.h"
#include "cobalt/dom/array_buffer_view.h"
#include "cobalt/script/environment_settings.h"
#include "cobalt/script/exception_state.h"

#if defined(STARBOARD)
#include "starboard/memory.h"
#endif

namespace cobalt {
namespace dom {

// TypedArray serves as the base of all array interfaces defined in
// https://www.khronos.org/registry/typedarray/specs/latest/#7
// An array interfaces should inherit from TypedArray<ElementType>, for
// example, Uint8Array should inherit from TypedArray<uint8>.  A macro
// named DEFINE_TYPED_ARRAY is provided at the end of this file for
// convenience.
template <typename ElementType>
class TypedArray : public ArrayBufferView {
 public:
  enum { kBytesPerElement = sizeof(ElementType) };

  // Create a new TypedArray of the specified length.  Each element is
  // initialized to 0 inside the ctor of ArrayBuffer.
  TypedArray(script::EnvironmentSettings* settings, uint32 length)
      : ArrayBufferView(new ArrayBuffer(settings, length * kBytesPerElement)) {}

  // Create a new TypedArray of the specified length and initialize it with the
  // given data.
  TypedArray(script::EnvironmentSettings* settings, const ElementType* data,
             uint32 length)
      : ArrayBufferView(new ArrayBuffer(settings, length * kBytesPerElement)) {
    DCHECK_EQ(this->length(), length);
#if defined(STARBOARD)
    SbMemoryCopy(this->data(), data, length * kBytesPerElement);
#else
    memcpy(this->data(), data, length * kBytesPerElement);
#endif
  }

  // Creates a new TypedArray and copies the elements of 'other' into this.
  TypedArray(script::EnvironmentSettings* settings,
             const scoped_refptr<TypedArray>& other)
      : ArrayBufferView(other->buffer()->Slice(settings, 0)) {}

  // TODO: Support constructors from Array types.
  // i.e. uint8[], float[], etc.

  // Create a view on top of the specified buffer.
  // Offset starts at byte_offset, length is byte_length.
  // This refers to the same underlying data as buffer.
  TypedArray(const scoped_refptr<ArrayBuffer>& buffer,
             script::ExceptionState* exception_state)
      : ArrayBufferView(buffer) {
    if (buffer->byte_length() % kBytesPerElement != 0) {
      exception_state->SetSimpleException(script::kWrongByteLengthMultiple,
                                          kBytesPerElement);
    }
  }

  TypedArray(const scoped_refptr<ArrayBuffer>& buffer, uint32 byte_offset,
             script::ExceptionState* exception_state)
      : ArrayBufferView(buffer, byte_offset,
                        buffer->byte_length() - byte_offset) {
    if (this->byte_offset() % kBytesPerElement != 0) {
      exception_state->SetSimpleException(script::kWrongByteOffsetMultiple,
                                          kBytesPerElement);
    } else if (buffer->byte_length() % kBytesPerElement != 0) {
      exception_state->SetSimpleException(script::kWrongByteLengthMultiple,
                                          kBytesPerElement);
    }
  }

  TypedArray(const scoped_refptr<ArrayBuffer>& buffer, uint32 byte_offset,
             uint32 length, script::ExceptionState* exception_state)
      : ArrayBufferView(buffer, byte_offset, length * kBytesPerElement) {
    if (this->byte_offset() % kBytesPerElement != 0) {
      exception_state->SetSimpleException(script::kWrongByteOffsetMultiple,
                                          kBytesPerElement);
    } else if (byte_offset + length * kBytesPerElement >
               buffer->byte_length()) {
      exception_state->SetSimpleException(script::kInvalidLength);
    }
  }

  // Create a new TypedArray that is a view into this existing array.
  template <typename SubarrayType>
  scoped_refptr<SubarrayType> SubarrayImpl(
      script::EnvironmentSettings* settings, int start, int end) {
    const int cur_length = static_cast<int>(length());
    int clamped_start;
    int clamped_end;
    ArrayBuffer::ClampRange(start, end, cur_length, &clamped_start,
                            &clamped_end);
    return new SubarrayType(
        settings, buffer(),
        static_cast<uint32>(byte_offset() + clamped_start * kBytesPerElement),
        static_cast<uint32>(clamped_end - clamped_start), NULL);
  }

  // Copy items from 'source' into this array. This array must already be at
  // least as large as 'source'.
  void Set(const scoped_refptr<TypedArray>& source, uint32 offset,
           script::ExceptionState* exception_state) {
    if (offset >= length() || length() - offset < source->length()) {
      exception_state->SetSimpleException(script::kInvalidLength);
      return;
    }
    uint32 source_offset = 0;
    while (source_offset < source->length()) {
#if defined(STARBOARD)
      SbMemoryCopy(data() + offset, source->data() + source_offset,
             sizeof(ElementType));
#else
      memcpy(data() + offset, source->data() + source_offset,
             sizeof(ElementType));
#endif
      ++offset;
      ++source_offset;
    }
  }

  void Set(const scoped_refptr<TypedArray>& source,
           script::ExceptionState* exception_state) {
    Set(source, 0, exception_state);
  }

  // Write a single element of the array.
  void Set(uint32 index, ElementType val) {
    if (index < length()) {
#if defined(STARBOARD)
      SbMemoryCopy(data() + index, &val, sizeof(ElementType));
#else
      memcpy(data() + index, &val, sizeof(ElementType));
#endif
    }
  }

  ElementType Get(uint32 index) const {
    if (index < length()) {
      ElementType val;
#if defined(STARBOARD)
      SbMemoryCopy(&val, data() + index, sizeof(ElementType));
#else
      memcpy(&val, data() + index, sizeof(ElementType));
#endif
      return val;
    } else {
      // TODO: an out of bounds index should return undefined.
      DLOG(ERROR) << "index " << index << " out of range " << length();
      return 0;
    }
  }

  uint32 length() const { return byte_length() / kBytesPerElement; }

  const ElementType* data() const {
    return reinterpret_cast<const ElementType*>(base_address());
  }
  ElementType* data() { return reinterpret_cast<ElementType*>(base_address()); }

  DEFINE_WRAPPABLE_TYPE(TypedArray);

 private:
  DISALLOW_COPY_AND_ASSIGN(TypedArray);
};

}  // namespace dom
}  // namespace cobalt

// This macro is necessary as every SubarrayType should define its own wrappable
// type.
// Example usage:
//   DEFINE_TYPED_ARRAY(Uint8Array, uint8);
//   DEFINE_TYPED_ARRAY(Float32Array, float);
#define DEFINE_TYPED_ARRAY(SubarrayType, ElementType)                          \
  class SubarrayType : public TypedArray<ElementType> {                        \
   public:                                                                     \
    SubarrayType(script::EnvironmentSettings* settings, uint32 length,         \
                 script::ExceptionState* exception_state)                      \
        : TypedArray<ElementType>(settings, length) {                          \
      UNREFERENCED_PARAMETER(exception_state);                                 \
    }                                                                          \
    SubarrayType(script::EnvironmentSettings* settings,                        \
                 const ElementType* data, uint32 length,                       \
                 script::ExceptionState* exception_state)                      \
        : TypedArray<ElementType>(settings, data, length) {                    \
      UNREFERENCED_PARAMETER(exception_state);                                 \
    }                                                                          \
    SubarrayType(script::EnvironmentSettings* settings,                        \
                 const scoped_refptr<SubarrayType>& other,                     \
                 script::ExceptionState* exception_state)                      \
        : TypedArray<ElementType>(settings, other.get()) {                     \
      UNREFERENCED_PARAMETER(exception_state);                                 \
    }                                                                          \
    SubarrayType(script::EnvironmentSettings* settings,                        \
                 const scoped_refptr<ArrayBuffer>& buffer,                     \
                 script::ExceptionState* exception_state)                      \
        : TypedArray<ElementType>(buffer.get(), exception_state) {             \
      UNREFERENCED_PARAMETER(settings);                                        \
    }                                                                          \
    SubarrayType(script::EnvironmentSettings* settings,                        \
                 const scoped_refptr<ArrayBuffer>& buffer, uint32 byte_offset, \
                 script::ExceptionState* exception_state)                      \
        : TypedArray<ElementType>(buffer, byte_offset, exception_state) {      \
      UNREFERENCED_PARAMETER(settings);                                        \
    }                                                                          \
    SubarrayType(script::EnvironmentSettings* settings,                        \
                 const scoped_refptr<ArrayBuffer>& buffer, uint32 byte_offset, \
                 uint32 byte_length, script::ExceptionState* exception_state)  \
        : TypedArray<ElementType>(buffer, byte_offset, byte_length,            \
                                  exception_state) {                           \
      UNREFERENCED_PARAMETER(settings);                                        \
    }                                                                          \
                                                                               \
    scoped_refptr<SubarrayType> Subarray(                                      \
        script::EnvironmentSettings* settings, int start, int end) {           \
      return SubarrayImpl<SubarrayType>(settings, start, end);                 \
    }                                                                          \
    scoped_refptr<SubarrayType> Subarray(                                      \
        script::EnvironmentSettings* settings, int start) {                    \
      return SubarrayImpl<SubarrayType>(settings, start,                       \
                                        static_cast<int>(length()));           \
    }                                                                          \
                                                                               \
    DEFINE_WRAPPABLE_TYPE(SubarrayType);                                       \
                                                                               \
   private:                                                                    \
    DISALLOW_COPY_AND_ASSIGN(SubarrayType);                                    \
  };

#endif  // COBALT_DOM_TYPED_ARRAY_H_
