// Copyright 2014 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_LIB_MAP_DATA_INTERNAL_H_
#define MOJO_PUBLIC_CPP_BINDINGS_LIB_MAP_DATA_INTERNAL_H_

#include "mojo/public/cpp/bindings/lib/array_internal.h"
#include "mojo/public/cpp/bindings/lib/validate_params.h"
#include "mojo/public/cpp/bindings/lib/validation_errors.h"

namespace mojo {
namespace internal {

namespace {
const ArrayValidateParams* GetMapKeyValidateParamsDefault() {
  // The memory allocated here never gets released because calling a
  // destructor at exit time makes clang unhappy.
  static const ArrayValidateParams* validate_params =
      new ArrayValidateParams(0, false, nullptr);
  return validate_params;
}

const ArrayValidateParams* GetMapKeyValidateParamsForStrings() {
  // The memory allocated here never gets released because calling a
  // destructor at exit time makes clang unhappy.
  static const ArrayValidateParams* validate_params = new ArrayValidateParams(
      0, false, new ArrayValidateParams(0, false, nullptr));
  return validate_params;
}

}  // namespace

template <typename MapKey>
struct MapKeyValidateParamsFactory {
  static const ArrayValidateParams* Get() {
    return GetMapKeyValidateParamsDefault();
  }
};

// For non-nullable strings only. (Which is OK; map keys can't be null.)
template <>
struct MapKeyValidateParamsFactory<mojo::internal::Array_Data<char>*> {
  static const ArrayValidateParams* Get() {
    return GetMapKeyValidateParamsForStrings();
  }
};

// Map serializes into a struct which has two arrays as struct fields, the keys
// and the values.
template <typename Key, typename Value>
class Map_Data {
 public:
  static Map_Data* New(Buffer* buf) {
    return new (buf->Allocate(sizeof(Map_Data))) Map_Data();
  }

  static bool Validate(const void* data,
                       BoundsChecker* bounds_checker,
                       const ArrayValidateParams* value_validate_params) {
    if (!data)
      return true;

    if (!ValidateStructHeaderAndClaimMemory(data, bounds_checker))
      return false;

    const Map_Data* object = static_cast<const Map_Data*>(data);
    // TODO(yzshen): In order to work with other bindings which still interprets
    // the |version| field as |num_fields|, |version| is set to 2.
    if (object->header_.num_bytes != sizeof(Map_Data) ||
        object->header_.version != 2) {
      ReportValidationError(VALIDATION_ERROR_UNEXPECTED_STRUCT_HEADER);
      return false;
    }

    if (!ValidateEncodedPointer(&object->keys.offset)) {
      ReportValidationError(VALIDATION_ERROR_ILLEGAL_POINTER);
      return false;
    }
    if (!object->keys.offset) {
      ReportValidationError(VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
                            "null key array in map struct");
      return false;
    }
    const ArrayValidateParams* key_validate_params =
        MapKeyValidateParamsFactory<Key>::Get();
    if (!Array_Data<Key>::Validate(DecodePointerRaw(&object->keys.offset),
                                   bounds_checker, key_validate_params)) {
      return false;
    }

    if (!ValidateEncodedPointer(&object->values.offset)) {
      ReportValidationError(VALIDATION_ERROR_ILLEGAL_POINTER);
      return false;
    }
    if (!object->values.offset) {
      ReportValidationError(VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
                            "null value array in map struct");
      return false;
    }
    if (!Array_Data<Value>::Validate(DecodePointerRaw(&object->values.offset),
                                     bounds_checker, value_validate_params)) {
      return false;
    }

    const ArrayHeader* key_header =
        static_cast<const ArrayHeader*>(DecodePointerRaw(&object->keys.offset));
    const ArrayHeader* value_header = static_cast<const ArrayHeader*>(
        DecodePointerRaw(&object->values.offset));
    if (key_header->num_elements != value_header->num_elements) {
      ReportValidationError(VALIDATION_ERROR_DIFFERENT_SIZED_ARRAYS_IN_MAP);
      return false;
    }

    return true;
  }

  StructHeader header_;

  ArrayPointer<Key> keys;
  ArrayPointer<Value> values;

  void EncodePointersAndHandles(std::vector<mojo::Handle>* handles) {
    Encode(&keys, handles);
    Encode(&values, handles);
  }

  void DecodePointersAndHandles(std::vector<mojo::Handle>* handles) {
    Decode(&keys, handles);
    Decode(&values, handles);
  }

 private:
  Map_Data() {
    header_.num_bytes = sizeof(*this);
    // TODO(yzshen): In order to work with other bindings which still interprets
    // the |version| field as |num_fields|, set it to version 2 for now.
    header_.version = 2;
  }
  ~Map_Data() = delete;
};
static_assert(sizeof(Map_Data<char, char>) == 24, "Bad sizeof(Map_Data)");

}  // namespace internal
}  // namespace mojo

#endif  // MOJO_PUBLIC_CPP_BINDINGS_LIB_MAP_DATA_INTERNAL_H_
