#include <fidl/my.config.lib/cpp/wire.h>
#include <fidl/my.config.lib/cpp/wire_types.h>
#include <lib/fidl/llcpp/message.h>
#include <lib/fidl/llcpp/traits.h>
#include <lib/zx/vmo.h>
#include <zircon/assert.h>
#include <zircon/process.h>
#include <zircon/processargs.h>
#include <zircon/status.h>
#include <zircon/syscalls.h>

#include <iostream>
#include <string>
#include <vector>

#include "cpp_elf_config_lib.h"

namespace cpp_elf_config_lib {

void Config::RecordInspect(inspect::Node* node) {
  node->RecordBool("my_flag", this->my_flag());
  node->RecordInt("my_int16", this->my_int16());
  node->RecordInt("my_int32", this->my_int32());
  node->RecordInt("my_int64", this->my_int64());
  node->RecordInt("my_int8", this->my_int8());
  node->RecordString("my_string", this->my_string());
  node->RecordUint("my_uint16", this->my_uint16());
  node->RecordUint("my_uint32", this->my_uint32());
  node->RecordUint("my_uint64", this->my_uint64());
  node->RecordUint("my_uint8", this->my_uint8());
  auto my_vector_of_flag_array_ = node->CreateUintArray(
      "my_vector_of_flag", this->my_vector_of_flag().size());
  for (size_t i = 0; i < this->my_vector_of_flag().size(); i++) {
    my_vector_of_flag_array_.Set(i, this->my_vector_of_flag()[i]);
  }
  node->Record(std::move(my_vector_of_flag_array_));
  auto my_vector_of_int16_array_ = node->CreateIntArray(
      "my_vector_of_int16", this->my_vector_of_int16().size());
  for (size_t i = 0; i < this->my_vector_of_int16().size(); i++) {
    my_vector_of_int16_array_.Set(i, this->my_vector_of_int16()[i]);
  }
  node->Record(std::move(my_vector_of_int16_array_));
  auto my_vector_of_int32_array_ = node->CreateIntArray(
      "my_vector_of_int32", this->my_vector_of_int32().size());
  for (size_t i = 0; i < this->my_vector_of_int32().size(); i++) {
    my_vector_of_int32_array_.Set(i, this->my_vector_of_int32()[i]);
  }
  node->Record(std::move(my_vector_of_int32_array_));
  auto my_vector_of_int64_array_ = node->CreateIntArray(
      "my_vector_of_int64", this->my_vector_of_int64().size());
  for (size_t i = 0; i < this->my_vector_of_int64().size(); i++) {
    my_vector_of_int64_array_.Set(i, this->my_vector_of_int64()[i]);
  }
  node->Record(std::move(my_vector_of_int64_array_));
  auto my_vector_of_int8_array_ = node->CreateIntArray(
      "my_vector_of_int8", this->my_vector_of_int8().size());
  for (size_t i = 0; i < this->my_vector_of_int8().size(); i++) {
    my_vector_of_int8_array_.Set(i, this->my_vector_of_int8()[i]);
  }
  node->Record(std::move(my_vector_of_int8_array_));
  auto my_vector_of_string_array_ = node->CreateStringArray(
      "my_vector_of_string", this->my_vector_of_string().size());
  for (size_t i = 0; i < this->my_vector_of_string().size(); i++) {
    auto ref = std::string_view(this->my_vector_of_string()[i].data());
    my_vector_of_string_array_.Set(i, ref);
  }
  node->Record(std::move(my_vector_of_string_array_));
  auto my_vector_of_uint16_array_ = node->CreateUintArray(
      "my_vector_of_uint16", this->my_vector_of_uint16().size());
  for (size_t i = 0; i < this->my_vector_of_uint16().size(); i++) {
    my_vector_of_uint16_array_.Set(i, this->my_vector_of_uint16()[i]);
  }
  node->Record(std::move(my_vector_of_uint16_array_));
  auto my_vector_of_uint32_array_ = node->CreateUintArray(
      "my_vector_of_uint32", this->my_vector_of_uint32().size());
  for (size_t i = 0; i < this->my_vector_of_uint32().size(); i++) {
    my_vector_of_uint32_array_.Set(i, this->my_vector_of_uint32()[i]);
  }
  node->Record(std::move(my_vector_of_uint32_array_));
  auto my_vector_of_uint64_array_ = node->CreateUintArray(
      "my_vector_of_uint64", this->my_vector_of_uint64().size());
  for (size_t i = 0; i < this->my_vector_of_uint64().size(); i++) {
    my_vector_of_uint64_array_.Set(i, this->my_vector_of_uint64()[i]);
  }
  node->Record(std::move(my_vector_of_uint64_array_));
  auto my_vector_of_uint8_array_ = node->CreateUintArray(
      "my_vector_of_uint8", this->my_vector_of_uint8().size());
  for (size_t i = 0; i < this->my_vector_of_uint8().size(); i++) {
    my_vector_of_uint8_array_.Set(i, this->my_vector_of_uint8()[i]);
  }
  node->Record(std::move(my_vector_of_uint8_array_));
}

std::ostream& operator<<(std::ostream& os, const Config& c) {
  os << "  my_flag: " << c.my_flag() << std::endl;
  os << "  my_int16: " << c.my_int16() << std::endl;
  os << "  my_int32: " << c.my_int32() << std::endl;
  os << "  my_int64: " << c.my_int64() << std::endl;
  os << "  my_int8: " << c.my_int8() << std::endl;
  os << "  my_string: " << c.my_string() << std::endl;
  os << "  my_uint16: " << c.my_uint16() << std::endl;
  os << "  my_uint32: " << c.my_uint32() << std::endl;
  os << "  my_uint64: " << c.my_uint64() << std::endl;
  os << "  my_uint8: " << c.my_uint8() << std::endl;
  os << "  my_vector_of_flag: [" << std::endl;
  for (auto value : c.my_vector_of_flag()) {
    os << "    " << value << "," << std::endl;
  }
  os << "]" << std::endl;
  os << "  my_vector_of_int16: [" << std::endl;
  for (auto value : c.my_vector_of_int16()) {
    os << "    " << value << "," << std::endl;
  }
  os << "]" << std::endl;
  os << "  my_vector_of_int32: [" << std::endl;
  for (auto value : c.my_vector_of_int32()) {
    os << "    " << value << "," << std::endl;
  }
  os << "]" << std::endl;
  os << "  my_vector_of_int64: [" << std::endl;
  for (auto value : c.my_vector_of_int64()) {
    os << "    " << value << "," << std::endl;
  }
  os << "]" << std::endl;
  os << "  my_vector_of_int8: [" << std::endl;
  for (auto value : c.my_vector_of_int8()) {
    os << "    " << value << "," << std::endl;
  }
  os << "]" << std::endl;
  os << "  my_vector_of_string: [" << std::endl;
  for (auto value : c.my_vector_of_string()) {
    os << "    " << value << "," << std::endl;
  }
  os << "]" << std::endl;
  os << "  my_vector_of_uint16: [" << std::endl;
  for (auto value : c.my_vector_of_uint16()) {
    os << "    " << value << "," << std::endl;
  }
  os << "]" << std::endl;
  os << "  my_vector_of_uint32: [" << std::endl;
  for (auto value : c.my_vector_of_uint32()) {
    os << "    " << value << "," << std::endl;
  }
  os << "]" << std::endl;
  os << "  my_vector_of_uint64: [" << std::endl;
  for (auto value : c.my_vector_of_uint64()) {
    os << "    " << value << "," << std::endl;
  }
  os << "]" << std::endl;
  os << "  my_vector_of_uint8: [" << std::endl;
  for (auto value : c.my_vector_of_uint8()) {
    os << "    " << value << "," << std::endl;
  }
  os << "]" << std::endl;
  return os;
}

template <class T>
std::vector<T> from_vector_view(fidl::VectorView<T> v) {
  size_t count = v.count();
  std::vector<T> data(count);
  for (size_t i = 0; i < count; i++) {
    data[i] = v[i];
  }
  return data;
}

std::vector<std::string> from_vector_string_view(
    fidl::VectorView<fidl::StringView> v) {
  size_t count = v.count();
  std::vector<std::string> data(count);
  for (size_t i = 0; i < count; i++) {
    data[i] = std::string(v[i].get());
  }
  return data;
}

Config Config::TakeFromStartupHandle() noexcept {
  // Get the VMO containing FIDL config
  zx_handle_t config_vmo_handle =
      zx_take_startup_handle(PA_VMO_COMPONENT_CONFIG);
  ZX_ASSERT_MSG(config_vmo_handle != ZX_HANDLE_INVALID,
                "Could not obtain Config VMO Handle");
  zx::vmo config_vmo(config_vmo_handle);

  // Get the size of the VMO
  uint64_t content_size_prop = 0;
  zx_status_t status = config_vmo.get_prop_content_size(&content_size_prop);
  ZX_ASSERT_MSG(status == ZX_OK, "Could not get content size of config VMO");
  size_t vmo_content_size = static_cast<size_t>(content_size_prop);

  // Checksum length must be correct
  uint16_t checksum_length = 0;
  status = config_vmo.read(&checksum_length, 0, 2);
  ZX_ASSERT_MSG(status == ZX_OK,
                "Could not read checksum length from config VMO");

  // Verify Checksum
  std::vector<uint8_t> checksum(checksum_length);
  status = config_vmo.read(checksum.data(), 2, checksum_length);
  ZX_ASSERT_MSG(status == ZX_OK, "Could not read checksum from config VMO");
  std::vector<uint8_t> expected_checksum{
      0xcd, 0x57, 0xb2, 0xa2, 0x89, 0xbb, 0xb6, 0x11, 0xcf, 0x81, 0x50,
      0xec, 0x06, 0xc5, 0x06, 0x4c, 0x7c, 0xae, 0x79, 0x0f, 0xaa, 0x73,
      0x0b, 0x6f, 0xa1, 0x02, 0xc3, 0x53, 0x7b, 0x94, 0xee, 0x1a};
  ZX_ASSERT_MSG(checksum == expected_checksum,
                "Invalid checksum for config VMO");

  // Read the FIDL struct into memory
  // Skip the checksum length + checksum + FIDL persistent header
  // Align the struct pointer to 8 bytes (as required by FIDL)
  size_t header = 2 + checksum_length + 8;
  size_t fidl_struct_size = vmo_content_size - header;
  std::unique_ptr<uint8_t[]> fidl_struct(new uint8_t[fidl_struct_size]);
  status = config_vmo.read(fidl_struct.get(), header, fidl_struct_size);
  ZX_ASSERT_MSG(status == ZX_OK, "Could not read FIDL struct from config VMO");

  // TODO(https://fxbug.dev/100147) use fidl::Unpersist(header_and_struct_bytes)
  // instead Decode the FIDL struct
  fidl::unstable::DecodedMessage<::my_config_lib::wire::Config> decoded(
      fidl::internal::WireFormatVersion::kV2, fidl_struct.get(),
      static_cast<uint32_t>(fidl_struct_size));
  ZX_ASSERT_MSG(decoded.ok(), "Could not decode Config FIDL structure");
  ::my_config_lib::wire::Config* fidl_config = decoded.PrimaryObject();

  // Convert the configuration into a new struct
  Config c{
      {.my_flag = fidl_config->my_flag,
       .my_int16 = fidl_config->my_int16,
       .my_int32 = fidl_config->my_int32,
       .my_int64 = fidl_config->my_int64,
       .my_int8 = fidl_config->my_int8,
       .my_string = std::string(fidl_config->my_string.get()),
       .my_uint16 = fidl_config->my_uint16,
       .my_uint32 = fidl_config->my_uint32,
       .my_uint64 = fidl_config->my_uint64,
       .my_uint8 = fidl_config->my_uint8,
       .my_vector_of_flag = from_vector_view(fidl_config->my_vector_of_flag),
       .my_vector_of_int16 = from_vector_view(fidl_config->my_vector_of_int16),
       .my_vector_of_int32 = from_vector_view(fidl_config->my_vector_of_int32),
       .my_vector_of_int64 = from_vector_view(fidl_config->my_vector_of_int64),
       .my_vector_of_int8 = from_vector_view(fidl_config->my_vector_of_int8),
       .my_vector_of_string =
           from_vector_string_view(fidl_config->my_vector_of_string),
       .my_vector_of_uint16 =
           from_vector_view(fidl_config->my_vector_of_uint16),
       .my_vector_of_uint32 =
           from_vector_view(fidl_config->my_vector_of_uint32),
       .my_vector_of_uint64 =
           from_vector_view(fidl_config->my_vector_of_uint64),
       .my_vector_of_uint8 =
           from_vector_view(fidl_config->my_vector_of_uint8)}};

  return c;
}

}  // namespace cpp_elf_config_lib
