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

#include "src/lib/fidl_codec/wire_types.h"

#include <zircon/fidl.h>

#include <rapidjson/error/en.h>

#include "src/lib/fidl_codec/library_loader.h"
#include "src/lib/fidl_codec/logger.h"
#include "src/lib/fidl_codec/type_visitor.h"
#include "src/lib/fidl_codec/wire_object.h"

// See wire_types.h for details.

namespace fidl_codec {
namespace {

class ToStringVisitor : public TypeVisitor {
 public:
  enum ExpandLevels : uint8_t {
    kNone,
    kOne,
    kAll,
  };

  explicit ToStringVisitor(const std::string& indent, ExpandLevels levels, std::string* result)
      : indent_(indent), levels_(levels), result_(result) {}
  ~ToStringVisitor() = default;

 private:
  ExpandLevels NextExpandLevels() {
    if (levels_ == ExpandLevels::kAll) {
      return ExpandLevels::kAll;
    }

    return ExpandLevels::kNone;
  }

  template <typename T>
  void VisitTypeWithMembers(const Type* type, const std::string& name,
                            const std::vector<T>& members, fit::function<bool(const T&)> body) {
    *result_ += name + " ";
    VisitType(type);

    if (levels_ == ExpandLevels::kNone) {
      return;
    }

    *result_ += " {";

    if (members.empty()) {
      *result_ += "}";
      return;
    }

    *result_ += "\n";

    for (const auto& member : members) {
      if (body(member)) {
        *result_ += ";\n";
      }
    }

    *result_ += indent_ + "}";
  }

  void VisitType(const Type* type) override { *result_ += type->Name(); }

  void VisitEnumType(const EnumType* type) override {
    VisitTypeWithMembers<EnumOrBitsMember>(type, "enum", type->enum_definition().members(),
                                           [this](const EnumOrBitsMember& member) {
                                             *result_ += indent_ + "  " + member.name() + " = ";
                                             if (member.negative()) {
                                               *result_ += "-";
                                             }
                                             *result_ += std::to_string(member.absolute_value());
                                             return true;
                                           });
  }

  void VisitBitsType(const BitsType* type) override {
    VisitTypeWithMembers<EnumOrBitsMember>(
        type, "bits", type->bits_definition().members(), [this](const EnumOrBitsMember& member) {
          *result_ +=
              indent_ + "  " + member.name() + " = " + std::to_string(member.absolute_value());
          return true;
        });
  }

  void VisitUnionType(const UnionType* type) override {
    VisitTypeWithMembers<std::unique_ptr<UnionMember>>(
        type, "union", type->union_definition().members(),
        [this](const std::unique_ptr<UnionMember>& member) {
          *result_ += indent_ + "  " + std::to_string(member->ordinal()) + ": ";
          ToStringVisitor visitor(indent_ + "  ", NextExpandLevels(), result_);
          member->type()->Visit(&visitor);
          *result_ += " " + std::string(member->name());
          return true;
        });
  }

  void VisitStructType(const StructType* type) override {
    VisitTypeWithMembers<std::unique_ptr<StructMember>>(
        type, "struct", type->struct_definition().members(),
        [this](const std::unique_ptr<StructMember>& member) {
          *result_ += indent_ + "  ";
          ToStringVisitor visitor(indent_ + "  ", NextExpandLevels(), result_);
          member->type()->Visit(&visitor);
          *result_ += " " + std::string(member->name());
          return true;
        });
  }

  void VisitArrayType(const ArrayType* type) override {
    *result_ += "array<";
    type->component_type()->Visit(this);
    *result_ += ">";
  }

  void VisitVectorType(const VectorType* type) override {
    *result_ += "vector<";
    type->component_type()->Visit(this);
    *result_ += ">";
  }

  void VisitTableType(const TableType* type) override {
    VisitTypeWithMembers<std::unique_ptr<TableMember>>(
        type, "table", type->table_definition().members(),
        [this](const std::unique_ptr<TableMember>& member) {
          if (!member) {
            return false;
          }
          *result_ += indent_ + "  ";
          *result_ += std::to_string(member->ordinal()) + ": ";
          ToStringVisitor visitor(indent_ + "  ", NextExpandLevels(), result_);
          member->type()->Visit(&visitor);
          *result_ += " " + std::string(member->name());
          return true;
        });
  }

  std::string indent_;
  ExpandLevels levels_;
  std::string* result_;
};

}  // namespace

std::string FidlMethodNameToCpp(std::string_view identifier) {
  std::string result(identifier);
  size_t start = 0;
  while ((start = result.find_first_of("./", start)) != std::string::npos) {
    result.replace(start, 1, "::");
    start += 2;
  }
  return result;
}

std::string Type::ToString(bool expand) const {
  std::string ret;
  ToStringVisitor visitor(
      "", expand ? ToStringVisitor::ExpandLevels::kAll : ToStringVisitor::ExpandLevels::kOne, &ret);
  Visit(&visitor);
  return ret;
}

void Type::PrettyPrint(const Value* value, PrettyPrinter& printer) const {
  printer << Red << "invalid" << ResetColor;
}

std::unique_ptr<Value> InvalidType::Decode(MessageDecoder* decoder, uint64_t offset) const {
  return std::make_unique<InvalidValue>();
}

void InvalidType::Visit(TypeVisitor* visitor) const { visitor->VisitInvalidType(this); }

std::unique_ptr<Value> EmptyPayloadType::Decode(MessageDecoder* decoder, uint64_t offset) const {
  return std::make_unique<EmptyPayloadValue>();
}

void EmptyPayloadType::Visit(TypeVisitor* visitor) const { visitor->VisitEmptyPayloadType(this); }

std::unique_ptr<Value> BoolType::Decode(MessageDecoder* decoder, uint64_t offset) const {
  auto byte = decoder->GetAddress(offset, 1);
  if (byte == nullptr) {
    return std::make_unique<InvalidValue>();
  }
  return std::make_unique<BoolValue>(*byte);
}

void BoolType::Visit(TypeVisitor* visitor) const { visitor->VisitBoolType(this); }

std::string Int8Type::Name() const {
  switch (kind_) {
    case Kind::kDecimal:
      return "int8";
    case Kind::kChar:
      return "char";
  }
}

void Int8Type::PrettyPrint(const Value* value, PrettyPrinter& printer) const {
  uint64_t absolute;
  bool negative;
  if (!value->GetIntegerValue(&absolute, &negative)) {
    printer << Red << "invalid" << ResetColor;
  } else {
    switch (kind_) {
      case Kind::kChar:
      case Kind::kDecimal:
        printer << Blue;
        if (negative) {
          printer << '-';
        }
        printer << absolute << ResetColor;
        break;
    }
  }
}

void Int8Type::Visit(TypeVisitor* visitor) const { visitor->VisitInt8Type(this); }

void Int16Type::PrettyPrint(const Value* value, PrettyPrinter& printer) const {
  uint64_t absolute;
  bool negative;
  if (!value->GetIntegerValue(&absolute, &negative)) {
    printer << Red << "invalid" << ResetColor;
  } else {
    switch (kind_) {
      case Kind::kDecimal:
        printer << Blue;
        if (negative) {
          printer << '-';
        }
        printer << absolute << ResetColor;
        break;
    }
  }
}

void Int16Type::Visit(TypeVisitor* visitor) const { visitor->VisitInt16Type(this); }

std::string Int32Type::Name() const {
  switch (kind_) {
    case Kind::kDecimal:
      return "int32";
    case Kind::kFutex:
      return "zx.futex_t";
  }
}

void Int32Type::PrettyPrint(const Value* value, PrettyPrinter& printer) const {
  uint64_t absolute;
  bool negative;
  if (!value->GetIntegerValue(&absolute, &negative)) {
    printer << Red << "invalid" << ResetColor;
  } else {
    switch (kind_) {
      case Kind::kDecimal:
        printer << Blue;
        if (negative) {
          printer << '-';
        }
        printer << absolute << ResetColor;
        break;
      case Kind::kFutex:
        printer << Red;
        if (negative) {
          printer << '-';
        }
        printer << absolute << ResetColor;
        break;
    }
  }
}

void Int32Type::Visit(TypeVisitor* visitor) const { visitor->VisitInt32Type(this); }

std::string Int64Type::Name() const {
  switch (kind_) {
    case Kind::kDecimal:
      return "int64";
    case Kind::kDuration:
      return "zx.duration";
    case Kind::kTime:
    case Kind::kMonotonicTime:
      return "zx.time";
  }
}

void Int64Type::PrettyPrint(const Value* value, PrettyPrinter& printer) const {
  uint64_t absolute;
  bool negative;
  if (!value->GetIntegerValue(&absolute, &negative)) {
    printer << Red << "invalid" << ResetColor;
  } else {
    switch (kind_) {
      case Kind::kDecimal:
        printer << Blue;
        if (negative) {
          printer << '-';
        }
        printer << absolute << ResetColor;
        break;
      case Kind::kDuration:
        if (negative) {
          absolute = -absolute;
        }
        printer.DisplayDuration(static_cast<zx_duration_t>(absolute));
        break;
      case Kind::kTime:
        if (negative) {
          absolute = -absolute;
        }
        printer.DisplayTime(static_cast<zx_time_t>(absolute));
        break;
      case Kind::kMonotonicTime:
        if (negative) {
          absolute = -absolute;
        }
        printer.DisplayDuration(static_cast<zx_duration_t>(absolute));
        break;
    }
  }
}

void Int64Type::Visit(TypeVisitor* visitor) const { visitor->VisitInt64Type(this); }

std::string Uint8Type::Name() const {
  switch (kind_) {
    case Kind::kDecimal:
    case Kind::kHexaDecimal:
      return "uint8";
    case Kind::kPacketGuestVcpuType:
      return "zx.packet_guest_vcpu::type";
  }
}

void Uint8Type::PrettyPrint(const Value* value, PrettyPrinter& printer) const {
  uint64_t absolute;
  bool negative;
  if (!value->GetIntegerValue(&absolute, &negative)) {
    printer << Red << "invalid" << ResetColor;
  } else {
    FX_DCHECK(!negative);
    switch (kind_) {
      case Kind::kDecimal:
        printer << Blue << absolute << ResetColor;
        break;
      case Kind::kHexaDecimal:
        printer.DisplayHexa8(static_cast<uint8_t>(absolute));
        break;
      case Kind::kPacketGuestVcpuType:
        printer.DisplayPacketGuestVcpuType(static_cast<uint8_t>(absolute));
    }
  }
}

void Uint8Type::Visit(TypeVisitor* visitor) const { visitor->VisitUint8Type(this); }

std::string Uint16Type::Name() const {
  switch (kind_) {
    case Kind::kDecimal:
    case Kind::kHexaDecimal:
      return "uint16";
    case Kind::kPacketPageRequestCommand:
      return "zx.packet_page_request::command";
  }
}

void Uint16Type::PrettyPrint(const Value* value, PrettyPrinter& printer) const {
  uint64_t absolute;
  bool negative;
  if (!value->GetIntegerValue(&absolute, &negative)) {
    printer << Red << "invalid" << ResetColor;
  } else {
    FX_DCHECK(!negative);
    switch (kind_) {
      case Kind::kDecimal:
        printer << Blue << absolute << ResetColor;
        break;
      case Kind::kHexaDecimal:
        printer.DisplayHexa16(static_cast<uint16_t>(absolute));
        break;
      case Kind::kPacketPageRequestCommand:
        printer.DisplayPacketPageRequestCommand(static_cast<uint16_t>(absolute));
        break;
    }
  }
}

void Uint16Type::Visit(TypeVisitor* visitor) const { visitor->VisitUint16Type(this); }

std::string Uint32Type::Name() const {
  switch (kind_) {
    case Kind::kBtiPerm:
      return "zx.bti_perm";
    case Kind::kCachePolicy:
      return "zx.cache_policy";
    case Kind::kChannelOption:
      return "uint32";
    case Kind::kClock:
      return "zx.clock";
    case Kind::kDecimal:
    case Kind::kHexaDecimal:
      return "uint32";
    case Kind::kExceptionChannelType:
      return "zx_info_thread_t::wait_exception_channel_type";
    case Kind::kExceptionState:
      return "zx.exception_state";
    case Kind::kFeatureKind:
      return "zx.feature_kind_t";
    case Kind::kGuestTrap:
      return "zx.guest_trap";
    case Kind::kInfoMapsType:
      return "zx.info_maps_type";
    case Kind::kInterruptFlags:
      return "zx.interrupt_flags";
    case Kind::kIommuType:
      return "zx.iommu_type";
    case Kind::kKtraceControlAction:
      return "zx.ktrace_control_action";
    case Kind::kObjectInfoTopic:
      return "zx.object_info_topic";
    case Kind::kObjType:
      return "zx.obj_type";
    case Kind::kPciBarType:
      return "zx.pci_bar_type";
    case Kind::kPolicyAction:
      return "zx.policy_action";
    case Kind::kPolicyCondition:
      return "zx.policy_condition";
    case Kind::kPolicyTopic:
      return "zx.policy_topic";
    case Kind::kPortPacketType:
      return "zx.port_packet::type";
    case Kind::kProfileInfoFlags:
      return "zx.profile_info_flags";
    case Kind::kPropType:
      return "zx.prop_type";
    case Kind::kRights:
      return "zx.rights";
    case Kind::kRsrcKind:
      return "zx.rsrc_kind";
    case Kind::kSignals:
      return "signals";
    case Kind::kSocketCreateOptions:
      return "zx.socket_create_options";
    case Kind::kSocketReadOptions:
      return "zx.socket_read_options";
    case Kind::kSocketDisposition:
      return "zx.socket_disposition";
    case Kind::kStatus:
      return "zx.status";
    case Kind::kSystemEventType:
      return "zx.system_event_type";
    case Kind::kSystemPowerctl:
      return "zx.system_powerctl";
    case Kind::kThreadState:
      return "zx.thread_state";
    case Kind::kThreadStateTopic:
      return "zx.thread_state_topic";
    case Kind::kTimerOption:
      return "zx.timer_option";
    case Kind::kVcpu:
      return "zx.vcpu";
    case Kind::kVmOption:
      return "zx.vm_option";
    case Kind::kVmoCreationOption:
      return "zx.vmo_creation_option";
    case Kind::kVmoOp:
      return "zx.vmo_op";
    case Kind::kVmoOption:
      return "zx.vmo_option";
    case Kind::kVmoType:
      return "zx.info_vmo_type";
  }
}

void Uint32Type::PrettyPrint(const Value* value, PrettyPrinter& printer) const {
  uint64_t absolute;
  bool negative;
  if (!value->GetIntegerValue(&absolute, &negative)) {
    printer << Red << "invalid" << ResetColor;
  } else {
    FX_DCHECK(!negative);
    switch (kind_) {
      case Kind::kBtiPerm:
        printer.DisplayBtiPerm(static_cast<uint32_t>(absolute));
        break;
      case Kind::kCachePolicy:
        printer.DisplayCachePolicy(static_cast<uint32_t>(absolute));
        break;
      case Kind::kChannelOption:
        printer.DisplayChannelOption(static_cast<uint32_t>(absolute));
        break;
      case Kind::kClock:
        printer.DisplayClock(static_cast<uint32_t>(absolute));
        break;
      case Kind::kDecimal:
        printer << Blue << absolute << ResetColor;
        break;
      case Kind::kExceptionChannelType:
        printer.DisplayExceptionChannelType(static_cast<uint32_t>(absolute));
        break;
      case Kind::kExceptionState:
        printer.DisplayExceptionState(static_cast<uint32_t>(absolute));
        break;
      case Kind::kFeatureKind:
        printer.DisplayFeatureKind(static_cast<uint32_t>(absolute));
        break;
      case Kind::kGuestTrap:
        printer.DisplayGuestTrap(static_cast<uint32_t>(absolute));
        break;
      case Kind::kHexaDecimal:
        printer.DisplayHexa32(static_cast<uint32_t>(absolute));
        break;
      case Kind::kInfoMapsType:
        printer.DisplayInfoMapsType(static_cast<uint32_t>(absolute));
        break;
      case Kind::kInterruptFlags:
        printer.DisplayInterruptFlags(static_cast<uint32_t>(absolute));
        break;
      case Kind::kIommuType:
        printer.DisplayIommuType(static_cast<uint32_t>(absolute));
        break;
      case Kind::kKtraceControlAction:
        printer.DisplayKtraceControlAction(static_cast<uint32_t>(absolute));
        break;
      case Kind::kObjectInfoTopic:
        printer.DisplayObjectInfoTopic(static_cast<uint32_t>(absolute));
        break;
      case Kind::kObjType:
        printer.DisplayObjType(static_cast<uint32_t>(absolute));
        break;
      case Kind::kPciBarType:
        printer.DisplayPciBarType(static_cast<uint32_t>(absolute));
        break;
      case Kind::kPolicyAction:
        printer.DisplayPolicyAction(static_cast<uint32_t>(absolute));
        break;
      case Kind::kPolicyCondition:
        printer.DisplayPolicyCondition(static_cast<uint32_t>(absolute));
        break;
      case Kind::kPolicyTopic:
        printer.DisplayPolicyTopic(static_cast<uint32_t>(absolute));
        break;
      case Kind::kProfileInfoFlags:
        printer.DisplayProfileInfoFlags(static_cast<uint32_t>(absolute));
        break;
      case Kind::kPropType:
        printer.DisplayPropType(static_cast<uint32_t>(absolute));
        break;
      case Kind::kPortPacketType:
        printer.DisplayPortPacketType(static_cast<uint32_t>(absolute));
        break;
      case Kind::kRights:
        printer.DisplayRights(static_cast<uint32_t>(absolute));
        break;
      case Kind::kRsrcKind:
        printer.DisplayRsrcKind(static_cast<uint32_t>(absolute));
        break;
      case Kind::kSignals:
        printer.DisplaySignals(static_cast<uint32_t>(absolute));
        break;
      case Kind::kSocketCreateOptions:
        printer.DisplaySocketCreateOptions(static_cast<uint32_t>(absolute));
        break;
      case Kind::kSocketReadOptions:
        printer.DisplaySocketReadOptions(static_cast<uint32_t>(absolute));
        break;
      case Kind::kSocketDisposition:
        printer.DisplaySocketDisposition(static_cast<uint32_t>(absolute));
        break;
      case Kind::kStatus:
        printer.DisplayStatus(static_cast<uint32_t>(absolute));
        break;
      case Kind::kSystemEventType:
        printer.DisplaySystemEventType(static_cast<uint32_t>(absolute));
        break;
      case Kind::kSystemPowerctl:
        printer.DisplaySystemPowerctl(static_cast<uint32_t>(absolute));
        break;
      case Kind::kThreadState:
        printer.DisplayThreadState(static_cast<uint32_t>(absolute));
        break;
      case Kind::kThreadStateTopic:
        printer.DisplayThreadStateTopic(static_cast<uint32_t>(absolute));
        break;
      case Kind::kTimerOption:
        printer.DisplayTimerOption(static_cast<uint32_t>(absolute));
        break;
      case Kind::kVcpu:
        printer.DisplayVcpu(static_cast<uint32_t>(absolute));
        break;
      case Kind::kVmOption:
        printer.DisplayVmOption(static_cast<uint32_t>(absolute));
        break;
      case Kind::kVmoCreationOption:
        printer.DisplayVmoCreationOption(static_cast<uint32_t>(absolute));
        break;
      case Kind::kVmoOp:
        printer.DisplayVmoOp(static_cast<uint32_t>(absolute));
        break;
      case Kind::kVmoOption:
        printer.DisplayVmoOption(static_cast<uint32_t>(absolute));
        break;
      case Kind::kVmoType:
        printer.DisplayVmoType(static_cast<uint32_t>(absolute));
        break;
    }
  }
}

void Uint32Type::Visit(TypeVisitor* visitor) const { visitor->VisitUint32Type(this); }

std::string Uint64Type::Name() const {
  switch (kind_) {
    case Kind::kDecimal:
    case Kind::kHexaDecimal:
      return "uint64";
    case Kind::kKoid:
      return "zx.koid";
    case Kind::kGpAddr:
      return "zx.gpaddr";
    case Kind::kPaddr:
      return "zx.paddr";
    case Kind::kSize:
      return "size";
    case Kind::kUintptr:
      return "uintptr";
    case Kind::kVaddr:
      return "zx.vaddr";
  }
}

void Uint64Type::PrettyPrint(const Value* value, PrettyPrinter& printer) const {
  uint64_t absolute;
  bool negative;
  if (!value->GetIntegerValue(&absolute, &negative)) {
    printer << Red << "invalid" << ResetColor;
  } else {
    FX_DCHECK(!negative);
    switch (kind_) {
      case Kind::kDecimal:
        printer << Blue << absolute << ResetColor;
        break;
      case Kind::kGpAddr:
        printer.DisplayGpAddr(absolute);
        break;
      case Kind::kHexaDecimal:
        printer.DisplayHexa64(absolute);
        break;
      case Kind::kKoid:
        printer.DisplayKoid(absolute);
        break;
      case Kind::kPaddr:
        printer.DisplayPaddr(absolute);
        break;
      case Kind::kSize:
        printer << Blue << absolute << ResetColor;
        break;
      case Kind::kUintptr:
        printer.DisplayUintptr(absolute);
        break;
      case Kind::kVaddr:
        printer.DisplayVaddr(absolute);
        break;
    }
  }
}

void Uint64Type::Visit(TypeVisitor* visitor) const { visitor->VisitUint64Type(this); }

void ActualAndRequestedType::PrettyPrint(const Value* value, PrettyPrinter& printer) const {
  auto actual_and_requested_value = value->AsActualAndRequestedValue();
  if (actual_and_requested_value == nullptr) {
    printer << Red << "invalid" << ResetColor;
  } else {
    printer << Blue << actual_and_requested_value->actual() << ResetColor << '/' << Blue
            << actual_and_requested_value->requested() << ResetColor;
  }
}

void ActualAndRequestedType::Visit(TypeVisitor* visitor) const {
  visitor->VisitActualAndRequestedType(this);
}

void Float32Type::Visit(TypeVisitor* visitor) const { visitor->VisitFloat32Type(this); }

void Float64Type::Visit(TypeVisitor* visitor) const { visitor->VisitFloat64Type(this); }

std::unique_ptr<Value> StringType::Decode(MessageDecoder* decoder, uint64_t offset) const {
  uint64_t string_length = 0;
  if (!decoder->GetValueAt(offset, &string_length)) {
    return std::make_unique<InvalidValue>();
  }
  offset += sizeof(string_length);

  bool is_null;
  uint64_t nullable_offset;
  if (!decoder->DecodeNullableHeader(offset, string_length, &is_null, &nullable_offset)) {
    return std::make_unique<InvalidValue>();
  }
  if (is_null) {
    return std::make_unique<NullValue>();
  }
  auto data = reinterpret_cast<const char*>(decoder->GetAddress(nullable_offset, string_length));
  if (data == nullptr) {
    return std::make_unique<InvalidValue>();
  }
  return std::make_unique<StringValue>(std::string_view(data, string_length));
}

void StringType::Visit(TypeVisitor* visitor) const { visitor->VisitStringType(this); }

std::unique_ptr<Value> HandleType::Decode(MessageDecoder* decoder, uint64_t offset) const {
  zx_handle_t handle = FIDL_HANDLE_ABSENT;
  decoder->GetValueAt(offset, &handle);
  if ((handle != FIDL_HANDLE_ABSENT) && (handle != FIDL_HANDLE_PRESENT)) {
    decoder->AddError() << std::hex << (decoder->absolute_offset() + offset) << std::dec
                        << ": Invalid value <" << std::hex << handle << std::dec
                        << "> for handle\n";
    handle = FIDL_HANDLE_ABSENT;
  }
  if (handle == FIDL_HANDLE_ABSENT) {
    zx_handle_disposition_t handle_disposition;
    handle_disposition.operation = fidl_codec::kNoHandleDisposition;
    handle_disposition.handle = FIDL_HANDLE_ABSENT;
    handle_disposition.type = ZX_OBJ_TYPE_NONE;
    handle_disposition.rights = 0;
    handle_disposition.result = ZX_OK;
    return std::make_unique<HandleValue>(handle_disposition);
  } else {
    return std::make_unique<HandleValue>(decoder->GetNextHandle());
  }
}

void HandleType::Visit(TypeVisitor* visitor) const { visitor->VisitHandleType(this); }

std::string EnumType::Name() const { return enum_definition_.name(); }

std::string EnumType::CppName() const { return FidlMethodNameToCpp(enum_definition_.name()); }

size_t EnumType::InlineSize(WireVersion version) const { return enum_definition_.Size(version); }

std::unique_ptr<Value> EnumType::Decode(MessageDecoder* decoder, uint64_t offset) const {
  return enum_definition_.type()->Decode(decoder, offset);
}

void EnumType::PrettyPrint(const Value* value, PrettyPrinter& printer) const {
  uint64_t absolute;
  bool negative;
  if (!value->GetIntegerValue(&absolute, &negative)) {
    printer << Red << "invalid" << ResetColor;
  } else {
    printer << Blue << enum_definition_.GetName(absolute, negative) << ResetColor;
  }
}

void EnumType::Visit(TypeVisitor* visitor) const { visitor->VisitEnumType(this); }

std::string BitsType::Name() const { return bits_definition_.name(); }

std::string BitsType::CppName() const { return FidlMethodNameToCpp(bits_definition_.name()); }

size_t BitsType::InlineSize(WireVersion version) const { return bits_definition_.Size(version); }

std::unique_ptr<Value> BitsType::Decode(MessageDecoder* decoder, uint64_t offset) const {
  return bits_definition_.type()->Decode(decoder, offset);
}

void BitsType::PrettyPrint(const Value* value, PrettyPrinter& printer) const {
  uint64_t absolute;
  bool negative;
  if (!value->GetIntegerValue(&absolute, &negative)) {
    printer << Red << "invalid" << ResetColor;
  } else {
    printer << Blue << bits_definition_.GetName(absolute, negative) << ResetColor;
  }
}

void BitsType::Visit(TypeVisitor* visitor) const { visitor->VisitBitsType(this); }

std::string UnionType::Name() const { return union_definition_.name(); }

std::string UnionType::CppName() const { return FidlMethodNameToCpp(union_definition_.name()); }

size_t UnionType::InlineSize(WireVersion version) const {
  // The inline size is the size of a 64 bit ordinal plus the size of an envelope which is 16 bytes.
  return 16;
}

std::unique_ptr<Value> UnionType::Decode(MessageDecoder* decoder, uint64_t offset) const {
  Ordinal64 ordinal = 0;
  if (decoder->GetValueAt(offset, &ordinal)) {
    if ((ordinal == 0) && !nullable_) {
      decoder->AddError() << std::hex << (decoder->absolute_offset() + offset) << std::dec
                          << ": Null envelope for a non nullable extensible union\n";
      return std::make_unique<InvalidValue>();
    }
  }

  offset += sizeof(ordinal);

  if (ordinal == 0) {
    if (!decoder->CheckNullEnvelope(offset)) {
      return std::make_unique<InvalidValue>();
    }
    return std::make_unique<NullValue>();
  }

  const UnionMember* member = union_definition_.MemberFromOrdinal(ordinal);
  if (member == nullptr) {
    return std::make_unique<InvalidValue>();
  }
  return std::make_unique<UnionValue>(*member, decoder->DecodeEnvelope(offset, member->type()));
}

void UnionType::Visit(TypeVisitor* visitor) const { visitor->VisitUnionType(this); }

std::string StructType::Name() const { return struct_definition_.name(); }

std::string StructType::CppName() const { return FidlMethodNameToCpp(struct_definition_.name()); }

size_t StructType::InlineSize(WireVersion version) const {
  return nullable_ ? sizeof(uintptr_t) : struct_definition_.Size(version);
}

std::unique_ptr<Value> StructType::Decode(MessageDecoder* decoder, uint64_t offset) const {
  if (nullable_) {
    bool is_null;
    uint64_t nullable_offset;
    if (!decoder->DecodeNullableHeader(offset, struct_definition_.Size(decoder->version()),
                                       &is_null, &nullable_offset)) {
      return std::make_unique<InvalidValue>();
    }
    if (is_null) {
      return std::make_unique<NullValue>();
    }
    offset = nullable_offset;
  }

  std::unique_ptr<StructValue> result = std::make_unique<StructValue>(struct_definition_);
  for (const auto& member : struct_definition_.members()) {
    std::unique_ptr<Value> value =
        member->type()->Decode(decoder, offset + member->Offset(decoder->version()));
    result->AddField(member.get(), std::move(value));
  }

  return result;
}

void StructType::Visit(TypeVisitor* visitor) const { visitor->VisitStructType(this); }

const Type* ElementSequenceType::GetComponentType() const { return component_type_.get(); }

void ElementSequenceType::Visit(TypeVisitor* visitor) const {
  visitor->VisitElementSequenceType(this);
}

bool ArrayType::IsArray() const { return true; }

std::string ArrayType::Name() const {
  return std::string("array<") + component_type()->Name() + ">";
}

std::string ArrayType::CppName() const {
  return std::string("std::array<") + component_type()->CppName() + ", " + std::to_string(count()) +
         ">";
}

void ArrayType::PrettyPrint(PrettyPrinter& printer) const {
  printer << "array<" << Green << component_type()->Name() << ResetColor << ">";
}

size_t ArrayType::InlineSize(WireVersion version) const {
  return component_type()->InlineSize(version) * count_;
}

std::unique_ptr<Value> ArrayType::Decode(MessageDecoder* decoder, uint64_t offset) const {
  auto result = std::make_unique<VectorValue>();
  for (uint64_t i = 0; i < count_; ++i) {
    result->AddValue(component_type()->Decode(decoder, offset));
    offset += component_type()->InlineSize(decoder->version());
  }
  return result;
}

void ArrayType::Visit(TypeVisitor* visitor) const { visitor->VisitArrayType(this); }

std::string VectorType::Name() const {
  return std::string("vector<") + component_type()->Name() + ">";
}

std::string VectorType::CppName() const {
  return std::string("std::vector<") + component_type()->CppName() + ">";
}

void VectorType::PrettyPrint(PrettyPrinter& printer) const {
  printer << "vector<" << Green << component_type()->Name() << ResetColor << ">";
}

std::unique_ptr<Value> VectorType::Decode(MessageDecoder* decoder, uint64_t offset) const {
  uint64_t element_count = 0;
  decoder->GetValueAt(offset, &element_count);
  offset += sizeof(element_count);
  bool is_null;
  uint64_t nullable_offset;
  if (!decoder->DecodeNullableHeader(
          offset, element_count * component_type()->InlineSize(decoder->version()), &is_null,
          &nullable_offset)) {
    return std::make_unique<InvalidValue>();
  }
  if (is_null) {
    return std::make_unique<NullValue>();
  }

  size_t component_size = component_type()->InlineSize(decoder->version());
  auto result = std::make_unique<VectorValue>();
  for (uint64_t i = 0;
       (i < element_count) && (nullable_offset + component_size <= decoder->num_bytes()); ++i) {
    result->AddValue(component_type()->Decode(decoder, nullable_offset));
    nullable_offset += component_size;
  }
  return result;
}

void VectorType::Visit(TypeVisitor* visitor) const { visitor->VisitVectorType(this); }

std::string TableType::Name() const { return table_definition_.name(); }

std::string TableType::CppName() const { return FidlMethodNameToCpp(table_definition_.name()); }

std::unique_ptr<Value> TableType::Decode(MessageDecoder* decoder, uint64_t offset) const {
  uint64_t member_count = 0;
  decoder->GetValueAt(offset, &member_count);
  offset += sizeof(member_count);

  bool is_null;
  uint64_t nullable_offset;
  size_t kEnvelopeSize = sizeof(uint32_t) + 2 * sizeof(uint16_t);
  if (!decoder->DecodeNullableHeader(offset, member_count * kEnvelopeSize, &is_null,
                                     &nullable_offset)) {
    return std::make_unique<InvalidValue>();
  }
  if (is_null) {
    decoder->AddError() << "Tables are not nullable.";
    return std::make_unique<InvalidValue>();
  }
  auto result = std::make_unique<TableValue>(table_definition_);
  for (uint64_t i = 1; i <= member_count; ++i) {
    const TableMember* member = table_definition_.MemberFromOrdinal(i);
    if (member == nullptr) {
      decoder->SkipEnvelope(nullable_offset);
    } else {
      std::unique_ptr<Value> value = decoder->DecodeEnvelope(nullable_offset, member->type());
      if (!value->IsNull()) {
        result->AddMember(member, std::move(value));
      }
    }
    nullable_offset += kEnvelopeSize;
  }
  return result;
}

void TableType::Visit(TypeVisitor* visitor) const { visitor->VisitTableType(this); }

std::unique_ptr<Value> FidlMessageType::Decode(MessageDecoder* decoder, uint64_t offset) const {
  return nullptr;
}

void FidlMessageType::Visit(TypeVisitor* visitor) const { visitor->VisitFidlMessageType(this); }

std::unique_ptr<Type> Type::ScalarTypeFromName(const std::string& type_name) {
  static std::map<std::string, std::function<std::unique_ptr<Type>()>> scalar_type_map_{
      {"bool", []() { return std::make_unique<BoolType>(); }},
      {"int8", []() { return std::make_unique<Int8Type>(); }},
      {"int16", []() { return std::make_unique<Int16Type>(); }},
      {"int32", []() { return std::make_unique<Int32Type>(); }},
      {"int64", []() { return std::make_unique<Int64Type>(); }},
      {"uint8", []() { return std::make_unique<Uint8Type>(); }},
      {"uint16", []() { return std::make_unique<Uint16Type>(); }},
      {"uint32", []() { return std::make_unique<Uint32Type>(); }},
      {"uint64", []() { return std::make_unique<Uint64Type>(); }},
      {"float32", []() { return std::make_unique<Float32Type>(); }},
      {"float64", []() { return std::make_unique<Float64Type>(); }},
  };
  auto it = scalar_type_map_.find(type_name);
  if (it != scalar_type_map_.end()) {
    return it->second();
  }
  return std::make_unique<InvalidType>();
}

std::unique_ptr<Type> InternalTypeFromName(const std::string& type_name) {
  // TODO(https://fxbug.dev/42061151): Remove "transport_error".
  if (type_name == "framework_error" || type_name == "transport_error") {
    return std::make_unique<EnumType>(Enum::FrameworkErrorEnum());
  }
  return std::make_unique<InvalidType>();
}

std::unique_ptr<Type> Type::TypeFromPrimitive(const rapidjson::Value& type) {
  if (!type.HasMember("subtype")) {
    FX_LOGS_OR_CAPTURE(ERROR) << "Invalid type";
    return std::make_unique<InvalidType>();
  }

  std::string subtype = type["subtype"].GetString();
  return ScalarTypeFromName(subtype);
}

std::unique_ptr<Type> Type::TypeFromInternal(const rapidjson::Value& type) {
  if (!type.HasMember("subtype")) {
    FX_LOGS_OR_CAPTURE(ERROR) << "Invalid internal type. Subtype missing";
    return std::make_unique<InvalidType>();
  }
  return InternalTypeFromName(type["subtype"].GetString());
}

std::unique_ptr<Type> Type::TypeFromIdentifier(LibraryLoader* loader,
                                               const rapidjson::Value& type) {
  if (!type.HasMember("identifier")) {
    FX_LOGS_OR_CAPTURE(ERROR) << "Invalid type";
    return std::make_unique<InvalidType>();
  }
  std::string id = type["identifier"].GetString();
  size_t split_index = id.find('/');
  std::string library_name = id.substr(0, split_index);
  Library* library = loader->GetLibraryFromName(library_name);
  if (library == nullptr) {
    FX_LOGS_OR_CAPTURE(ERROR) << "Unknown type for identifier: " << id;
    return std::make_unique<InvalidType>();
  }

  bool is_nullable = false;
  if (type.HasMember("nullable")) {
    is_nullable = type["nullable"].GetBool();
  }
  return library->TypeFromIdentifier(is_nullable, id);
}

std::unique_ptr<Type> Type::GetType(LibraryLoader* loader, const rapidjson::Value& type) {
  if (!type.HasMember("kind")) {
    FX_LOGS_OR_CAPTURE(ERROR) << "Invalid type";
    return std::make_unique<InvalidType>();
  }
  std::string kind = type["kind"].GetString();
  if (kind == "string") {
    return std::make_unique<StringType>();
  }
  if (kind == "handle") {
    // For some reason object type and rights are stored as strings.
    std::string rights_string = type["rights"].GetString();
    std::string obj_type_string = type["obj_type"].GetString();
    bool nullable = type["nullable"].GetBool();
    std::optional<zx_obj_type_t> rights;
    if (auto rights_int = std::atoi(rights_string.c_str()); rights_int != -1) {
      rights = std::optional<zx_rights_t>(static_cast<zx_obj_type_t>(rights_int));
    }
    std::optional<zx_obj_type_t> obj_type;
    if (auto obj_type_int = std::atoi(obj_type_string.c_str()); obj_type_int != -1) {
      obj_type = std::optional<zx_obj_type_t>(static_cast<zx_obj_type_t>(obj_type_int));
    }
    return std::make_unique<HandleType>(rights, obj_type, nullable);
  }
  if (kind == "array") {
    const rapidjson::Value& element_type = type["element_type"];
    uint32_t element_count = static_cast<uint32_t>(
        std::strtol(type["element_count"].GetString(), nullptr, kDecimalBase));
    return std::make_unique<ArrayType>(GetType(loader, element_type), element_count);
  }
  if (kind == "vector") {
    const rapidjson::Value& element_type = type["element_type"];
    return std::make_unique<VectorType>(GetType(loader, element_type));
  }
  if (kind == "request") {
    std::optional<zx_obj_type_t> object_type = std::nullopt;
    std::optional<zx_obj_type_t> rights = std::nullopt;
    std::string_view transport = type["protocol_transport"].GetString();
    if (transport == "Channel") {
      object_type = std::optional<zx_obj_type_t>(ZX_OBJ_TYPE_CHANNEL);
      rights = std::optional<zx_rights_t>(ZX_DEFAULT_CHANNEL_RIGHTS);
    }
    return std::make_unique<HandleType>(rights, object_type, type["nullable"].GetBool());
  }
  if (kind == "primitive") {
    return Type::TypeFromPrimitive(type);
  }
  if (kind == "identifier") {
    return Type::TypeFromIdentifier(loader, type);
  }
  if (kind == "internal") {
    return Type::TypeFromInternal(type);
  }
  FX_LOGS_OR_CAPTURE(ERROR) << "Invalid type " << kind;
  return std::make_unique<InvalidType>();
}

}  // namespace fidl_codec
