/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

namespace datasketches {

template<typename Array, typename Policy, typename Allocator>
update_array_tuple_sketch<Array, Policy, Allocator>::update_array_tuple_sketch(uint8_t lg_cur_size, uint8_t lg_nom_size, resize_factor rf,
    float p, uint64_t theta, uint64_t seed, const Policy& policy, const Allocator& allocator):
Base(lg_cur_size, lg_nom_size, rf, p, theta, seed, policy, allocator) {}

template<typename Array, typename Policy, typename Allocator>
uint8_t update_array_tuple_sketch<Array, Policy, Allocator>::get_num_values() const {
  return this->policy_.get_num_values();
}

template<typename Array, typename Policy, typename Allocator>
compact_array_tuple_sketch<Array, Allocator> update_array_tuple_sketch<Array, Policy, Allocator>::compact(bool ordered) const {
  return compact_array_tuple_sketch<Array, Allocator>(*this, ordered);
}

// builder

template<typename Array, typename Policy, typename Allocator>
update_array_tuple_sketch<Array, Policy, Allocator>::builder::builder(const Policy& policy, const Allocator& allocator):
tuple_base_builder<builder, Policy, Allocator>(policy, allocator) {}

template<typename Array, typename Policy, typename Allocator>
auto update_array_tuple_sketch<Array, Policy, Allocator>::builder::build() const -> update_array_tuple_sketch {
  return update_array_tuple_sketch(this->starting_lg_size(), this->lg_k_, this->rf_, this->p_, this->starting_theta(), this->seed_, this->policy_, this->allocator_);
}

// compact sketch

template<typename Array, typename Allocator>
template<typename S>
compact_array_tuple_sketch<Array, Allocator>::compact_array_tuple_sketch(const S& other, bool ordered):
Base(other, ordered), num_values_(other.get_num_values()) {}

template<typename Array, typename Allocator>
compact_array_tuple_sketch<Array, Allocator>::compact_array_tuple_sketch(bool is_empty, bool is_ordered,
    uint16_t seed_hash, uint64_t theta, std::vector<Entry, AllocEntry>&& entries, uint8_t num_values):
Base(is_empty, is_ordered, seed_hash, theta, std::move(entries)), num_values_(num_values) {}

template<typename Array, typename Allocator>
compact_array_tuple_sketch<Array, Allocator>::compact_array_tuple_sketch(uint8_t num_values, Base&& base):
Base(std::move(base)), num_values_(num_values) {}

template<typename Array, typename Allocator>
uint8_t compact_array_tuple_sketch<Array, Allocator>::get_num_values() const {
  return num_values_;
}

template<typename Array, typename Allocator>
void compact_array_tuple_sketch<Array, Allocator>::serialize(std::ostream& os) const {
  const uint8_t preamble_longs = 1;
  write(os, preamble_longs);
  const uint8_t serial_version = SERIAL_VERSION;
  write(os, serial_version);
  const uint8_t family = SKETCH_FAMILY;
  write(os, family);
  const uint8_t type = SKETCH_TYPE;
  write(os, type);
  const uint8_t flags_byte(
    (this->is_empty() ? 1 << flags::IS_EMPTY : 0) |
    (this->get_num_retained() > 0 ? 1 << flags::HAS_ENTRIES : 0) |
    (this->is_ordered() ? 1 << flags::IS_ORDERED : 0)
  );
  write(os, flags_byte);
  write(os, num_values_);
  const uint16_t seed_hash = this->get_seed_hash();
  write(os, seed_hash);
  write(os, this->theta_);
  if (this->get_num_retained() > 0) {
    const uint32_t num_entries = static_cast<uint32_t>(this->entries_.size());
    write(os, num_entries);
    const uint32_t unused32 = 0;
    write(os, unused32);
    for (const auto& it: this->entries_) {
      write(os, it.first);
    }
    for (const auto& it: this->entries_) {
      write(os, it.second.data(), it.second.size() * sizeof(typename Array::value_type));
    }
  }
}

template<typename Array, typename Allocator>
auto compact_array_tuple_sketch<Array, Allocator>::serialize(unsigned header_size_bytes) const -> vector_bytes {
  const uint8_t preamble_longs = 1;
  const size_t size = header_size_bytes + 16 // preamble and theta
      + (this->entries_.size() > 0 ? 8 : 0)
      + (sizeof(uint64_t) + sizeof(typename Array::value_type) * num_values_) * this->entries_.size();
  vector_bytes bytes(size, 0, this->entries_.get_allocator());
  uint8_t* ptr = bytes.data() + header_size_bytes;

  ptr += copy_to_mem(preamble_longs, ptr);
  const uint8_t serial_version = SERIAL_VERSION;
  ptr += copy_to_mem(serial_version, ptr);
  const uint8_t family = SKETCH_FAMILY;
  ptr += copy_to_mem(family, ptr);
  const uint8_t type = SKETCH_TYPE;
  ptr += copy_to_mem(type, ptr);
  const uint8_t flags_byte(
    (this->is_empty() ? 1 << flags::IS_EMPTY : 0) |
    (this->get_num_retained() ? 1 << flags::HAS_ENTRIES : 0) |
    (this->is_ordered() ? 1 << flags::IS_ORDERED : 0)
  );
  ptr += copy_to_mem(flags_byte, ptr);
  ptr += copy_to_mem(num_values_, ptr);
  const uint16_t seed_hash = this->get_seed_hash();
  ptr += copy_to_mem(seed_hash, ptr);
  ptr += copy_to_mem((this->theta_), ptr);
  if (this->get_num_retained() > 0) {
    const uint32_t num_entries = static_cast<uint32_t>(this->entries_.size());
    ptr += copy_to_mem(num_entries, ptr);
    ptr += sizeof(uint32_t); // unused
    for (const auto& it: this->entries_) {
      ptr += copy_to_mem(it.first, ptr);
    }
    for (const auto& it: this->entries_) {
      ptr += copy_to_mem(it.second.data(), ptr, it.second.size() * sizeof(typename Array::value_type));
    }
  }
  return bytes;
}

template<typename Array, typename Allocator>
compact_array_tuple_sketch<Array, Allocator> compact_array_tuple_sketch<Array, Allocator>::deserialize(std::istream& is, uint64_t seed, const Allocator& allocator) {
  read<uint8_t>(is); // unused
  const auto serial_version = read<uint8_t>(is);
  const auto family = read<uint8_t>(is);
  const auto type = read<uint8_t>(is);
  const auto flags_byte = read<uint8_t>(is);
  const auto num_values = read<uint8_t>(is);
  const auto seed_hash = read<uint16_t>(is);
  checker<true>::check_serial_version(serial_version, SERIAL_VERSION);
  checker<true>::check_sketch_family(family, SKETCH_FAMILY);
  checker<true>::check_sketch_type(type, SKETCH_TYPE);
  const bool has_entries = flags_byte & (1 << flags::HAS_ENTRIES);
  if (has_entries) checker<true>::check_seed_hash(seed_hash, compute_seed_hash(seed));

  const auto theta = read<uint64_t>(is);
  std::vector<Entry, AllocEntry> entries(allocator);
  if (has_entries) {
    const auto num_entries = read<uint32_t>(is);
    read<uint32_t>(is); // unused
    entries.reserve(num_entries);
    std::vector<uint64_t, AllocU64> keys(num_entries, 0, allocator);
    read(is, keys.data(), num_entries * sizeof(uint64_t));
    for (size_t i = 0; i < num_entries; ++i) {
      Array summary(num_values, 0, allocator);
      read(is, summary.data(), num_values * sizeof(typename Array::value_type));
      entries.emplace_back(keys[i], std::move(summary));
    }
  }
  if (!is.good()) throw std::runtime_error("error reading from std::istream");
  const bool is_empty = flags_byte & (1 << flags::IS_EMPTY);
  const bool is_ordered = flags_byte & (1 << flags::IS_ORDERED);
  return compact_array_tuple_sketch<Array, Allocator>(is_empty, is_ordered, seed_hash, theta, std::move(entries), num_values);
}

template<typename Array, typename Allocator>
compact_array_tuple_sketch<Array, Allocator> compact_array_tuple_sketch<Array, Allocator>::deserialize(const void* bytes, size_t size, uint64_t seed, const Allocator& allocator) {
  ensure_minimum_memory(size, 16);
  const char* ptr = static_cast<const char*>(bytes);
  ptr += sizeof(uint8_t); // unused
  uint8_t serial_version;
  ptr += copy_from_mem(ptr, serial_version);
  uint8_t family;
  ptr += copy_from_mem(ptr, family);
  uint8_t type;
  ptr += copy_from_mem(ptr, type);
  uint8_t flags_byte;
  ptr += copy_from_mem(ptr, flags_byte);
  uint8_t num_values;
  ptr += copy_from_mem(ptr, num_values);
  uint16_t seed_hash;
  ptr += copy_from_mem(ptr, seed_hash);
  checker<true>::check_serial_version(serial_version, SERIAL_VERSION);
  checker<true>::check_sketch_family(family, SKETCH_FAMILY);
  checker<true>::check_sketch_type(type, SKETCH_TYPE);
  const bool has_entries = flags_byte & (1 << flags::HAS_ENTRIES);
  if (has_entries) checker<true>::check_seed_hash(seed_hash, compute_seed_hash(seed));

  uint64_t theta;
  ptr += copy_from_mem(ptr, theta);
  std::vector<Entry, AllocEntry> entries(allocator);
  if (has_entries) {
    ensure_minimum_memory(size, 24);
    uint32_t num_entries;
    ptr += copy_from_mem(ptr, num_entries);
    ptr += sizeof(uint32_t); // unused
    ensure_minimum_memory(size, 24 + (sizeof(uint64_t) + sizeof(typename Array::value_type) * num_values) * num_entries);
    entries.reserve(num_entries);
    std::vector<uint64_t, AllocU64> keys(num_entries, 0, allocator);
    ptr += copy_from_mem(ptr, keys.data(), sizeof(uint64_t) * num_entries);
    for (size_t i = 0; i < num_entries; ++i) {
      Array summary(num_values, 0, allocator);
      ptr += copy_from_mem(ptr, summary.data(), num_values * sizeof(typename Array::value_type));
      entries.emplace_back(keys[i], std::move(summary));
    }
  }
  const bool is_empty = flags_byte & (1 << flags::IS_EMPTY);
  const bool is_ordered = flags_byte & (1 << flags::IS_ORDERED);
  return compact_array_tuple_sketch<Array, Allocator>(is_empty, is_ordered, seed_hash, theta, std::move(entries), num_values);
}

} /* namespace datasketches */
