// 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 <sstream>
#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);
}

size_t RawValue::DisplaySize(const Type* /*for_type*/, size_t /*remaining_size*/) const {
  return (data_.size() == 0) ? 0 : 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);
}

size_t BoolValue::DisplaySize(const Type* /*for_type*/, size_t /*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;
}

size_t IntegerValue::DisplaySize(const Type* for_type, size_t /*remaining_size*/) const {
  std::stringstream dummyStream;
  auto dummyPrinter = PrettyPrinter(dummyStream, WithoutColors, true, "", INT_MAX, false);
  for_type->PrettyPrint(this, dummyPrinter);
  return dummyStream.str().length();
}

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);
}

size_t DoubleValue::DisplaySize(const Type* for_type, size_t /*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);
}

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

void StringValue::PrettyPrint(const Type* for_type, PrettyPrinter& printer) const {
  printer.DisplayString(string_);
}

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

bool HandleValue::NeedsToLoadHandleInfo(int64_t timestamp, zx_koid_t tid,
                                        semantic::HandleSemantic* handle_semantic) const {
  if (handle_.handle == ZX_HANDLE_INVALID) {
    return false;
  }
  return handle_semantic->NeedsToLoadHandleInfo(timestamp, tid, handle_.handle);
}

size_t HandleValue::DisplaySize(const Type* /*for_type*/, size_t /*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(int64_t timestamp, zx_koid_t tid,
                                       semantic::HandleSemantic* handle_semantic) const {
  return value_->NeedsToLoadHandleInfo(timestamp, tid, handle_semantic);
}

size_t UnionValue::DisplaySize(const Type* for_type, size_t remaining_size) const {
  // Two characters for the opening brace ("{ ") + three characters for equal
  // (" = ") and two characters for the closing brace (" }").
  constexpr int kExtraSize = 7;
  size_t size = member_.name().size() + kExtraSize;
  // Two characters for ": ".
  size += 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()) {
    printer << "{ " << member_.name() << ": ";
    member_.type()->PrettyPrint(printer);
    printer << " = ";
    value_->PrettyPrint(member_.type(), printer);
    printer << " }";
  } else {
    printer << "{\n";
    {
      Indent indent(printer);
      printer << member_.name() << ": ";
      member_.type()->PrettyPrint(printer);
      printer << " = ";
      value_->PrettyPrint(member_.type(), printer);
      printer << '\n';
    }
    printer << "}";
  }
}

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

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

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

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

size_t StructValue::DisplaySize(const Type* for_type, size_t remaining_size) const {
  size_t 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 += member->name().size() + kExtraSize;
    // Two characters for ": ".
    size += 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() << ": ";
      member->type()->PrettyPrint(printer);
      printer << " = ";
      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() << ": ";
        member->type()->PrettyPrint(printer);
        printer << " = ";
        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(int64_t timestamp, zx_koid_t tid,
                                        semantic::HandleSemantic* handle_semantic) const {
  for (const auto& value : values_) {
    if (value->NeedsToLoadHandleInfo(timestamp, tid, handle_semantic)) {
      return true;
    }
  }
  return false;
}

size_t VectorValue::DisplaySize(const Type* for_type, size_t remaining_size) const {
  FX_DCHECK(for_type != nullptr);
  if (values_.empty()) {
    return 2;  // The two brackets.
  }
  if (is_string_) {
    return values_.size() + 2;  // The string and the two quotes.
  }
  const Type* component_type = for_type->GetComponentType();
  FX_DCHECK(component_type != nullptr);
  size_t 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);
        printer << Red;
        for (const auto& value : values_) {
          printer << static_cast<char>(value->GetUint8Value());
        }
        printer << ResetColor;
      }
      printer << '\n';
      printer << ']';
    } else {
      printer << Red << '"';
      for (const auto& value : values_) {
        printer << static_cast<char>(value->GetUint8Value());
      }
      printer << '"' << ResetColor;
    }
  } 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_) {
        size_t 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(int64_t timestamp, zx_koid_t tid,
                                       semantic::HandleSemantic* handle_semantic) const {
  for (const auto& member : members_) {
    if (member.second->NeedsToLoadHandleInfo(timestamp, tid, handle_semantic)) {
      return true;
    }
  }
  return false;
}

size_t TableValue::DisplaySize(const Type* for_type, size_t remaining_size) const {
  size_t 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 == nullptr) || it->second->IsNull())
        continue;
      // Two characters for the separator ("{ " or ", "), three characters for " = ".
      size += member->name().size() + 2 + 3;
      // Two characters for ": ".
      size += 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 {
  size_t 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 == nullptr) || 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 == nullptr) || 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_disposition_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_((unknown_direction_ || is_request_) ? std::move(message->decoded_request())
                                                           : nullptr),
      request_errors_((unknown_direction_ || is_request_) ? message->request_error_stream().str()
                                                          : ""),
      decoded_response_(
          (unknown_direction_ || !is_request_) ? std::move(message->decoded_response()) : nullptr),
      response_errors_((unknown_direction_ || !is_request_) ? message->response_error_stream().str()
                                                            : "") {}

bool FidlMessageValue::NeedsToLoadHandleInfo(int64_t timestamp, zx_koid_t tid,
                                             semantic::HandleSemantic* handle_semantic) const {
  for (const auto& handle : handles_) {
    auto inferred_handle_info = handle_semantic->GetInferredHandleInfo(tid, handle.handle);
    if (inferred_handle_info == nullptr) {
      return true;
    }
  }
  return false;
}

size_t FidlMessageValue::DisplaySize(const Type* for_type, size_t 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
