// 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_object.h"

#include <lib/syslog/cpp/macros.h>

#include <iomanip>
#include <iostream>
#include <memory>
#include <vector>

#include <rapidjson/stringbuffer.h>
#include <rapidjson/writer.h>

#include "src/lib/fidl_codec/display_handle.h"
#include "src/lib/fidl_codec/json_visitor.h"
#include "src/lib/fidl_codec/library_loader.h"
#include "src/lib/fidl_codec/printer.h"
#include "src/lib/fidl_codec/status.h"
#include "src/lib/fidl_codec/visitor.h"
#include "src/lib/fidl_codec/wire_types.h"

namespace fidl_codec {

std::string DocumentToString(rapidjson::Document* document) {
  rapidjson::StringBuffer output;
  rapidjson::Writer<rapidjson::StringBuffer> writer(output);
  document->Accept(writer);
  return output.GetString();
}

void InvalidValue::Visit(Visitor* visitor, const Type* for_type) const {
  visitor->VisitInvalidValue(this, for_type);
}

void NullValue::Visit(Visitor* visitor, const Type* for_type) const {
  visitor->VisitNullValue(this, for_type);
}

int RawValue::DisplaySize(const Type* /*for_type*/, int /*remaining_size*/) const {
  return (data_.size() == 0) ? 0 : static_cast<int>(data_.size()) * 3 - 1;
}

void RawValue::PrettyPrint(const Type* for_type, PrettyPrinter& printer) const {
  if (data_.size() == 0) {
    return;
  }
  size_t buffer_size = data_.size() * 3;
  std::vector<char> buffer(buffer_size);
  for (size_t i = 0; i < data_.size(); ++i) {
    if (i != 0) {
      buffer[i * 3 - 1] = ' ';
    }
    snprintf(buffer.data() + (i * 3), 4, "%02x", data_[i]);
  }
  printer << buffer.data();
}

void RawValue::Visit(Visitor* visitor, const Type* for_type) const {
  visitor->VisitRawValue(this, for_type);
}

int BoolValue::DisplaySize(const Type* /*for_type*/, int /*remaining_size*/) const {
  constexpr int kTrueSize = 4;
  constexpr int kFalseSize = 5;
  return value_ ? kTrueSize : kFalseSize;
}

void BoolValue::PrettyPrint(const Type* for_type, PrettyPrinter& printer) const {
  printer << Blue << (value_ ? "true" : "false") << ResetColor;
}

void BoolValue::Visit(Visitor* visitor, const Type* for_type) const {
  visitor->VisitBoolValue(this, for_type);
}

uint8_t IntegerValue::GetUint8Value() const {
  return (!negative_ && (absolute_value_ < 0x100)) ? static_cast<uint8_t>(absolute_value_) : 0;
}

int IntegerValue::DisplaySize(const Type* for_type, int /*remaining_size*/) const {
  bool sign_size = negative_ ? 1 : 0;
  return std::to_string(absolute_value_).size() + sign_size;
}

void IntegerValue::PrettyPrint(const Type* for_type, PrettyPrinter& printer) const {
  FX_DCHECK(for_type != nullptr);
  for_type->PrettyPrint(this, printer);
}

void IntegerValue::Visit(Visitor* visitor, const Type* for_type) const {
  visitor->VisitIntegerValue(this, for_type);
}

int DoubleValue::DisplaySize(const Type* for_type, int /*remaining_size*/) const {
  return std::to_string(value_).size();
}

void DoubleValue::PrettyPrint(const Type* for_type, PrettyPrinter& printer) const {
  FX_DCHECK(for_type != nullptr);
  for_type->PrettyPrint(this, printer);
}

void DoubleValue::Visit(Visitor* visitor, const Type* for_type) const {
  visitor->VisitDoubleValue(this, for_type);
}

int StringValue::DisplaySize(const Type* /*for_type*/, int /*remaining_size*/) const {
  return static_cast<int>(string_.size()) + 2;  // The two quotes.
}

void StringValue::PrettyPrint(const Type* for_type, PrettyPrinter& printer) const {
  printer << Red << '"' << string_ << '"' << ResetColor;
}

void StringValue::Visit(Visitor* visitor, const Type* for_type) const {
  visitor->VisitStringValue(this, for_type);
}

bool HandleValue::NeedsToLoadHandleInfo(zx_koid_t pid,
                                        semantic::HandleSemantic* handle_semantic) const {
  auto description = handle_semantic->GetHandleDescription(pid, handle_.handle);
  return (description == nullptr) || (description->koid() == ZX_KOID_INVALID);
}

int HandleValue::DisplaySize(const Type* /*for_type*/, int /*remaining_size*/) const {
  return std::to_string(handle_.handle).size();
}

void HandleValue::PrettyPrint(const Type* /*for_type*/, PrettyPrinter& printer) const {
  printer.DisplayHandle(handle_);
}

void HandleValue::Visit(Visitor* visitor, const Type* for_type) const {
  visitor->VisitHandleValue(this, for_type);
}

bool UnionValue::NeedsToLoadHandleInfo(zx_koid_t pid,
                                       semantic::HandleSemantic* handle_semantic) const {
  return value_->NeedsToLoadHandleInfo(pid, handle_semantic);
}

int UnionValue::DisplaySize(const Type* for_type, int remaining_size) const {
  // Two characters for the opening brace ("{ ") + three characters for equal
  // (" = ") and two characters for the closing brace (" }").
  constexpr int kExtraSize = 7;
  int size = static_cast<int>(member_.name().size()) + kExtraSize;
  // Two characters for ": ".
  size += static_cast<int>(member_.type()->Name().size()) + 2;
  size += value_->DisplaySize(member_.type(), remaining_size - size);
  return size;
}

void UnionValue::PrettyPrint(const Type* for_type, PrettyPrinter& printer) const {
  if (DisplaySize(for_type, printer.remaining_size()) <= printer.remaining_size()) {
    std::string type_name = member_.type()->Name();
    printer << "{ " << member_.name() << ": " << Green << type_name << ResetColor << " = ";
    value_->PrettyPrint(member_.type(), printer);
    printer << " }";
  } else {
    std::string type_name = member_.type()->Name();
    printer << "{\n";
    {
      Indent indent(printer);
      printer << member_.name() << ": " << Green << type_name << ResetColor << " = ";
      value_->PrettyPrint(member_.type(), printer);
      printer << '\n';
    }
    printer << "}";
  }
}

void UnionValue::Visit(Visitor* visitor, const Type* for_type) const {
  visitor->VisitUnionValue(this, for_type);
}

const Value* StructValue::GetFieldValue(std::string_view field_name) const {
  for (const auto& field : fields_) {
    if (field.first->name() == field_name) {
      return field.second.get();
    }
  }
  return nullptr;
}

void StructValue::AddField(std::string_view name, std::unique_ptr<Value> value) {
  StructMember* member = struct_definition_.SearchMember(name);
  if (member != nullptr) {
    AddField(member, std::move(value));
  }
}

bool StructValue::NeedsToLoadHandleInfo(zx_koid_t pid,
                                        semantic::HandleSemantic* handle_semantic) const {
  for (const auto& field : fields_) {
    if (field.second->NeedsToLoadHandleInfo(pid, handle_semantic)) {
      return true;
    }
  }
  return false;
}

int StructValue::DisplaySize(const Type* for_type, int remaining_size) const {
  int size = 0;
  for (const auto& member : struct_definition_.members()) {
    auto it = fields_.find(member.get());
    if (it == fields_.end())
      continue;
    // Two characters for the separator ("{ " or ", ") and three characters for
    // equal (" = ").
    constexpr int kExtraSize = 5;
    size += static_cast<int>(member->name().size()) + kExtraSize;
    // Two characters for ": ".
    size += static_cast<int>(member->type()->Name().size()) + 2;
    size += it->second->DisplaySize(member->type(), remaining_size - size);
    if (size > remaining_size) {
      return size;
    }
  }
  // Two characters for the closing brace (" }").
  size += 2;
  return size;
}

void StructValue::PrettyPrint(const Type* for_type, PrettyPrinter& printer) const {
  if (fields_.empty()) {
    printer << "{}";
  } else if (DisplaySize(for_type, printer.remaining_size()) <= printer.remaining_size()) {
    const char* separator = "{ ";
    for (const auto& member : struct_definition_.members()) {
      auto it = fields_.find(member.get());
      if (it == fields_.end())
        continue;
      printer << separator << member->name() << ": " << Green << member->type()->Name()
              << ResetColor << " = ";
      it->second->PrettyPrint(member->type(), printer);
      separator = ", ";
    }
    printer << " }";
  } else {
    printer << "{\n";
    {
      Indent indent(printer);
      for (const auto& member : struct_definition_.members()) {
        auto it = fields_.find(member.get());
        if (it == fields_.end())
          continue;
        std::string type_name = member->type()->Name();
        printer << member->name() << ": " << Green << type_name << ResetColor << " = ";
        it->second->PrettyPrint(member->type(), printer);
        printer << "\n";
      }
    }
    printer << '}';
  }
}

void StructValue::Visit(Visitor* visitor, const Type* for_type) const {
  visitor->VisitStructValue(this, for_type);
}

void StructValue::ExtractJson(rapidjson::Document::AllocatorType& allocator,
                              rapidjson::Value& result) const {
  JsonVisitor visitor(&result, &allocator);

  Visit(&visitor, nullptr);
}

bool VectorValue::NeedsToLoadHandleInfo(zx_koid_t pid,
                                        semantic::HandleSemantic* handle_semantic) const {
  for (const auto& value : values_) {
    if (value->NeedsToLoadHandleInfo(pid, handle_semantic)) {
      return true;
    }
  }
  return false;
}

int VectorValue::DisplaySize(const Type* for_type, int remaining_size) const {
  FX_DCHECK(for_type != nullptr);
  if (values_.empty()) {
    return 2;  // The two brackets.
  }
  if (is_string_) {
    return static_cast<int>(values_.size() + 2);  // The string and the two quotes.
  }
  const Type* component_type = for_type->GetComponentType();
  FX_DCHECK(component_type != nullptr);
  int size = 0;
  for (const auto& value : values_) {
    // Two characters for the separator ("[ " or ", ").
    size += value->DisplaySize(component_type, remaining_size - size) + 2;
    if (size > remaining_size) {
      return size;
    }
  }
  // Two characters for the closing bracket (" ]").
  size += 2;
  return size;
}

void VectorValue::PrettyPrint(const Type* for_type, PrettyPrinter& printer) const {
  FX_DCHECK(for_type != nullptr);
  if (values_.empty()) {
    printer << "[]";
  } else if (is_string_) {
    if (has_new_line_) {
      printer << "[\n";
      {
        Indent indent(printer);
        for (const auto& value : values_) {
          printer << static_cast<char>(value->GetUint8Value());
        }
      }
      printer << '\n';
      printer << ']';
    } else {
      printer << '"';
      for (const auto& value : values_) {
        printer << static_cast<char>(value->GetUint8Value());
      }
      printer << '"';
    }
  } else if (DisplaySize(for_type, printer.remaining_size()) <= printer.remaining_size()) {
    const Type* component_type = for_type->GetComponentType();
    FX_DCHECK(component_type != nullptr);
    const char* separator = "[ ";
    for (const auto& value : values_) {
      printer << separator;
      separator = ", ";
      value->PrettyPrint(component_type, printer);
    }
    printer << " ]";
  } else {
    const Type* component_type = for_type->GetComponentType();
    FX_DCHECK(component_type != nullptr);
    printer << "[\n";
    {
      Indent indent(printer);
      for (const auto& value : values_) {
        int value_size = value->DisplaySize(component_type, printer.remaining_size());
        if (!printer.LineEmpty()) {
          if (value_size + 3 > printer.remaining_size()) {
            printer << "\n";
          } else {
            printer << ", ";
          }
        }
        value->PrettyPrint(component_type, printer);
      }
      printer << '\n';
    }
    printer << ']';
  }
}

void VectorValue::Visit(Visitor* visitor, const Type* for_type) const {
  visitor->VisitVectorValue(this, for_type);
}

bool TableValue::AddMember(std::string_view name, std::unique_ptr<Value> value) {
  const TableMember* member = table_definition_.GetMember(name);
  if (member == nullptr) {
    return false;
  }
  AddMember(member, std::move(value));
  return true;
}

bool TableValue::NeedsToLoadHandleInfo(zx_koid_t pid,
                                       semantic::HandleSemantic* handle_semantic) const {
  for (const auto& member : members_) {
    if (member.second->NeedsToLoadHandleInfo(pid, handle_semantic)) {
      return true;
    }
  }
  return false;
}

int TableValue::DisplaySize(const Type* for_type, int remaining_size) const {
  int size = 0;
  for (const auto& member : table_definition_.members()) {
    if ((member != nullptr) && !member->reserved()) {
      auto it = members_.find(member.get());
      if ((it == members_.end()) || it->second->IsNull())
        continue;
      // Two characters for the separator ("{ " or ", "), three characters for " = ".
      size += static_cast<int>(member->name().size()) + 2 + 3;
      // Two characters for ": ".
      size += static_cast<int>(member->type()->Name().size()) + 2;
      size += it->second->DisplaySize(member->type(), remaining_size - size);
      if (size > remaining_size) {
        return size;
      }
    }
  }
  // Two characters for the closing brace (" }").
  size += 2;
  return size;
}

void TableValue::PrettyPrint(const Type* for_type, PrettyPrinter& printer) const {
  int display_size = DisplaySize(for_type, printer.remaining_size());
  if (display_size == 2) {
    printer << "{}";
  } else if (display_size <= printer.remaining_size()) {
    const char* separator = "{ ";
    for (const auto& member : table_definition_.members()) {
      if ((member != nullptr) && !member->reserved()) {
        auto it = members_.find(member.get());
        if ((it == members_.end()) || it->second->IsNull())
          continue;
        printer << separator << member->name() << ": " << Green << member->type()->Name()
                << ResetColor << " = ";
        separator = ", ";
        it->second->PrettyPrint(member->type(), printer);
      }
    }
    printer << " }";
  } else {
    printer << "{\n";
    {
      Indent indent(printer);
      for (const auto& member : table_definition_.members()) {
        if ((member != nullptr) && !member->reserved()) {
          auto it = members_.find(member.get());
          if ((it == members_.end()) || it->second->IsNull())
            continue;
          std::string type_name = member->type()->Name();
          printer << member->name() << ": " << Green << type_name << ResetColor << " = ";
          it->second->PrettyPrint(member->type(), printer);
          printer << "\n";
        }
      }
    }
    printer << '}';
  }
}

void TableValue::Visit(Visitor* visitor, const Type* for_type) const {
  visitor->VisitTableValue(this, for_type);
}

FidlMessageValue::FidlMessageValue(fidl_codec::DecodedMessage* message, std::string global_errors,
                                   const uint8_t* bytes, uint32_t num_bytes,
                                   const zx_handle_info_t* handles, uint32_t num_handles)
    : txid_(message->txid()),
      ordinal_(message->ordinal()),
      global_errors_(std::move(global_errors)),
      epitaph_error_(
          (message->ordinal() == kFidlOrdinalEpitaph) ? StatusName(message->epitaph_error()) : ""),
      received_(message->received()),
      is_request_(message->is_request()),
      unknown_direction_(message->direction() == Direction::kUnknown),
      method_(message->method()),
      bytes_(bytes, bytes + num_bytes),
      handles_(handles, handles + num_handles),
      decoded_request_(std::move(message->decoded_request())),
      request_errors_(message->request_error_stream().str()),
      decoded_response_(std::move(message->decoded_response())),
      response_errors_(message->response_error_stream().str()) {}

bool FidlMessageValue::NeedsToLoadHandleInfo(zx_koid_t pid,
                                             semantic::HandleSemantic* handle_semantic) const {
  for (const auto& handle : handles_) {
    auto description = handle_semantic->GetHandleDescription(pid, handle.handle);
    if (description == nullptr) {
      return true;
    }
  }
  return false;
}

int FidlMessageValue::DisplaySize(const Type* for_type, int remaining_size) const { return 0; }

void FidlMessageValue::PrettyPrint(const Type* for_type, PrettyPrinter& printer) const {
  PrintMessage(printer);
  DumpMessage(printer);
}

void FidlMessageValue::PrintMessage(PrettyPrinter& printer) const {
  if (!global_errors_.empty()) {
    printer << global_errors_;
    return;
  }
  if (ordinal_ == kFidlOrdinalEpitaph) {
    printer << fidl_codec::WhiteOnMagenta << (received_ ? "received" : "sent") << " epitaph"
            << fidl_codec::ResetColor << ' ' << fidl_codec::Red << epitaph_error_
            << fidl_codec::ResetColor << "\n";
    return;
  }

  if (unknown_direction_) {
    bool matched_request = (decoded_request_ != nullptr) && request_errors_.empty();
    bool matched_response = (decoded_response_ != nullptr) && response_errors_.empty();
    if (matched_request || matched_response) {
      printer << fidl_codec::Red << "Can't determine request/response." << fidl_codec::ResetColor
              << " it can be:\n";
      fidl_codec::Indent indent(printer);
      PrintMessageBody(printer);
      return;
    }
  }
  PrintMessageBody(printer);
}

void FidlMessageValue::PrintMessageBody(PrettyPrinter& printer) const {
  if (matched_request() && (is_request_ || unknown_direction_)) {
    printer << fidl_codec::WhiteOnMagenta << (received_ ? "received" : "sent") << " request"
            << fidl_codec::ResetColor << ' ' << fidl_codec::Green
            << method_->enclosing_interface().name() << '.' << method_->name()
            << fidl_codec::ResetColor << " = ";
    if (printer.pretty_print()) {
      decoded_request_->PrettyPrint(nullptr, printer);
      printer << '\n';
    } else {
      rapidjson::Document actual_request;
      if (decoded_request_ != nullptr) {
        decoded_request_->ExtractJson(actual_request.GetAllocator(), actual_request);
      }
      printer << DocumentToString(&actual_request) << '\n';
    }
  }
  if (matched_response() && (!is_request_ || unknown_direction_)) {
    printer << fidl_codec::WhiteOnMagenta << (received_ ? "received" : "sent")
            << ((method_->request() != nullptr) ? " response" : " event") << fidl_codec::ResetColor
            << ' ' << fidl_codec::Green << method_->enclosing_interface().name() << '.'
            << method_->name() << fidl_codec::ResetColor << " = ";
    if (printer.pretty_print()) {
      decoded_response_->PrettyPrint(nullptr, printer);
      printer << '\n';
    } else {
      rapidjson::Document actual_response;
      if (decoded_response_ != nullptr) {
        decoded_response_->ExtractJson(actual_response.GetAllocator(), actual_response);
      }
      printer << DocumentToString(&actual_response) << '\n';
    }
  }
  if (matched_request() || matched_response()) {
    return;
  }
  if (!request_errors_.empty()) {
    printer << fidl_codec::Red << (received_ ? "received" : "sent") << " request errors"
            << fidl_codec::ResetColor << ":\n";
    {
      Indent indent(printer);
      printer << request_errors_;
    }
    if (decoded_request_ != nullptr) {
      printer << fidl_codec::WhiteOnMagenta << (received_ ? "received" : "sent") << " request"
              << fidl_codec::ResetColor << ' ' << fidl_codec::Green
              << method_->enclosing_interface().name() << '.' << method_->name()
              << fidl_codec::ResetColor << " = ";
      decoded_request_->PrettyPrint(nullptr, printer);
      printer << '\n';
    }
  }
  if (!response_errors_.empty()) {
    printer << fidl_codec::Red << (received_ ? "received" : "sent")
            << ((method_->request() != nullptr) ? " response errors" : " event errors")
            << fidl_codec::ResetColor << ":\n";
    {
      Indent indent(printer);
      printer << response_errors_;
    }
    if (decoded_response_ != nullptr) {
      printer << fidl_codec::WhiteOnMagenta << (received_ ? "received" : "sent")
              << ((method_->request() != nullptr) ? " response" : " event")
              << fidl_codec::ResetColor << ' ' << fidl_codec::Green
              << method_->enclosing_interface().name() << '.' << method_->name()
              << fidl_codec::ResetColor << " = ";
      decoded_response_->PrettyPrint(nullptr, printer);
      printer << '\n';
    }
  }
}

void FidlMessageValue::DumpMessage(PrettyPrinter& printer) const {
  constexpr int kPatternColorSize = 4;
  constexpr int kPatternSize = 8;
  constexpr int kLineSize = 16;
  constexpr int kLineHandleSize = 4;
  constexpr int kCharactersPerByte = 2;
  if ((decoded_request_ == nullptr) && (decoded_response_ == nullptr) &&
      (ordinal_ != kFidlOrdinalEpitaph)) {
    printer << fidl_codec::Red << "Can't decode message: ";
  } else if (printer.DumpMessages()) {
    printer << "Message: ";
  } else {
    return;
  }
  printer << "num_bytes=" << bytes_.size() << " num_handles=" << handles_.size();
  if (txid_ != 0) {
    printer << " txid=" << std::hex << txid_ << std::dec;
  }
  if (ordinal_ != 0) {
    printer << " ordinal=" << std::hex << ordinal_ << std::dec;
    if (method_ != nullptr) {
      printer << '(' << method_->enclosing_interface().name() << '.' << method_->name() << ')';
    }
  }
  printer << fidl_codec::ResetColor << '\n';
  {
    Indent indent_data(printer);
    printer << "data=";
    const char* separator = "";
    Indent indent_dump(printer);
    for (uint32_t i = 0; i < bytes_.size(); ++i) {
      // Display 16 bytes per line.
      if (i % kLineSize == 0) {
        std::vector<char> buffer(sizeof(uint32_t) * kCharactersPerByte + 1);
        snprintf(buffer.data(), buffer.size(), "%04x", i);
        printer << separator << "\n";
        printer << buffer.data() << ": ";
        separator = "";
      }
      // Display 4 bytes in red then four bytes in black ...
      if (i % kPatternSize == 0) {
        printer << fidl_codec::Red;
      } else if (i % kPatternColorSize == 0) {
        printer << fidl_codec::ResetColor;
      }
      std::vector<char> buffer(sizeof(uint8_t) * kCharactersPerByte + 1);
      snprintf(buffer.data(), buffer.size(), "%02x", bytes_[i]);
      printer << separator << buffer.data();
      separator = ", ";
    }
    printer << fidl_codec::ResetColor << '\n';
  }
  if (handles_.size() > 0) {
    Indent indent_data(printer);
    printer << "handles=";
    Indent indent_dump(printer);
    const char* separator = "";
    for (uint32_t i = 0; i < handles_.size(); ++i) {
      // Display 4 bytes per line.
      if (i % kLineHandleSize == 0) {
        std::vector<char> buffer(sizeof(uint32_t) * kCharactersPerByte + 1);
        snprintf(buffer.data(), buffer.size(), "%04x", i);
        printer << separator << "\n";
        printer << buffer.data() << ": ";
        separator = "";
      }
      std::vector<char> buffer(sizeof(zx_handle_t) * kCharactersPerByte + 1);
      snprintf(buffer.data(), buffer.size(), "%08x", handles_[i].handle);
      printer << separator << buffer.data();
      separator = ", ";
    }
    printer << '\n';
  }
}

void FidlMessageValue::Visit(Visitor* visitor, const Type* for_type) const {
  visitor->VisitFidlMessageValue(this, for_type);
}

}  // namespace fidl_codec
