// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef MOJO_PUBLIC_CPP_BINDINGS_ARRAY_H_
#define MOJO_PUBLIC_CPP_BINDINGS_ARRAY_H_

#include <string.h>

#include <algorithm>
#include <string>
#include <vector>

#include "mojo/public/cpp/bindings/lib/array_internal.h"
#include "mojo/public/cpp/bindings/lib/bindings_internal.h"
#include "mojo/public/cpp/bindings/lib/template_util.h"
#include "mojo/public/cpp/bindings/type_converter.h"

namespace mojo {

template <typename T>
class Array {
  MOJO_MOVE_ONLY_TYPE(Array)
 public:
  typedef internal::ArrayTraits<T, internal::IsMoveOnlyType<T>::value> Traits;
  typedef typename Traits::ConstRefType ConstRefType;
  typedef typename Traits::RefType RefType;
  typedef typename Traits::StorageType StorageType;
  typedef typename Traits::ForwardType ForwardType;

  typedef internal::Array_Data<typename internal::WrapperTraits<T>::DataType>
      Data_;

  Array() : is_null_(true) {}
  explicit Array(size_t size) : vec_(size), is_null_(false) {
    Traits::Initialize(&vec_);
  }
  ~Array() { Traits::Finalize(&vec_); }

  Array(Array&& other) : is_null_(true) { Take(&other); }
  Array& operator=(Array&& other) {
    Take(&other);
    return *this;
  }

  static Array New(size_t size) { return Array(size).Pass(); }

  template <typename U>
  static Array From(const U& other) {
    return TypeConverter<Array, U>::Convert(other);
  }

  template <typename U>
  U To() const {
    return TypeConverter<U, Array>::Convert(*this);
  }

  void reset() {
    if (!vec_.empty()) {
      Traits::Finalize(&vec_);
      vec_.clear();
    }
    is_null_ = true;
  }

  bool is_null() const { return is_null_; }

  ConstRefType front() const { return vec_.front(); }
  RefType front() { return vec_.front(); }

  size_t size() const { return vec_.size(); }

  ConstRefType at(size_t offset) const { return Traits::at(&vec_, offset); }
  ConstRefType operator[](size_t offset) const { return at(offset); }

  RefType at(size_t offset) { return Traits::at(&vec_, offset); }
  RefType operator[](size_t offset) { return at(offset); }

  void push_back(ForwardType value) {
    is_null_ = false;
    Traits::PushBack(&vec_, value);
  }

  void resize(size_t size) {
    is_null_ = false;
    Traits::Resize(&vec_, size);
  }

  const std::vector<StorageType>& storage() const { return vec_; }
  operator const std::vector<StorageType>&() const { return vec_; }

  void Swap(Array* other) {
    std::swap(is_null_, other->is_null_);
    vec_.swap(other->vec_);
  }
  void Swap(std::vector<StorageType>* other) {
    is_null_ = false;
    vec_.swap(*other);
  }

  // Please note that calling this method will fail compilation if the element
  // type cannot be cloned (which usually means that it is a Mojo handle type or
  // a type contains Mojo handles).
  Array Clone() const {
    Array result;
    result.is_null_ = is_null_;
    Traits::Clone(vec_, &result.vec_);
    return result.Pass();
  }

  bool Equals(const Array& other) const {
    if (is_null() != other.is_null())
      return false;
    if (size() != other.size())
      return false;
    for (size_t i = 0; i < size(); ++i) {
      if (!internal::ValueTraits<T>::Equals(at(i), other.at(i)))
        return false;
    }
    return true;
  }

 private:
  typedef std::vector<StorageType> Array::*Testable;

 public:
  operator Testable() const { return is_null_ ? 0 : &Array::vec_; }

 private:
  void Take(Array* other) {
    reset();
    Swap(other);
  }

  std::vector<StorageType> vec_;
  bool is_null_;
};

template <typename T, typename E>
struct TypeConverter<Array<T>, std::vector<E>> {
  static Array<T> Convert(const std::vector<E>& input) {
    Array<T> result(input.size());
    for (size_t i = 0; i < input.size(); ++i)
      result[i] = TypeConverter<T, E>::Convert(input[i]);
    return result.Pass();
  }
};

template <typename E, typename T>
struct TypeConverter<std::vector<E>, Array<T>> {
  static std::vector<E> Convert(const Array<T>& input) {
    std::vector<E> result;
    if (!input.is_null()) {
      result.resize(input.size());
      for (size_t i = 0; i < input.size(); ++i)
        result[i] = TypeConverter<E, T>::Convert(input[i]);
    }
    return result;
  }
};

}  // namespace mojo

#endif  // MOJO_PUBLIC_CPP_BINDINGS_ARRAY_H_
