// 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.

#ifndef SRC_LIB_FIDL_CODEC_WIRE_OBJECT_H_
#define SRC_LIB_FIDL_CODEC_WIRE_OBJECT_H_

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

#include <map>
#include <memory>
#include <string_view>
#include <vector>

#include "src/lib/fidl_codec/library_loader.h"
#include "src/lib/fidl_codec/message_decoder.h"

namespace fidl_codec {

class FidlMessageValue;
class HandleValue;
class StringValue;
class StructValue;
class VectorValue;
class Visitor;

// Base class for all the values we can find within a message.
class Value {
 public:
  Value() = default;
  virtual ~Value() = default;

  virtual bool IsNull() const { return false; }

  // Returns the uint8_t value of the value. If the value is not a uint8_t value this returns zero.
  // This is used to eventually display a vector of uint8_t values as a string.
  virtual uint8_t GetUint8Value() const { return 0; }

  // Gets the integer value of the value. Returns false if the node can't compute an integer value.
  // For floating point values, the floating point value is converted to the nearest integer
  // value.
  virtual bool GetIntegerValue(uint64_t* absolute, bool* negative) const { return false; }

  // Gets the floating point value of the value. Returns false if the node can't compute a floating
  // point value. For integer values, we can lost precision during the conversion.
  virtual bool GetDoubleValue(double* result) const { return false; }

  // Methods to downcast a value.
  virtual const StringValue* AsStringValue() const { return nullptr; }
  virtual const HandleValue* AsHandleValue() const { return nullptr; }
  virtual StructValue* AsStructValue() { return nullptr; }
  virtual const StructValue* AsStructValue() const { return nullptr; }
  virtual const VectorValue* AsVectorValue() const { return nullptr; }
  virtual const FidlMessageValue* AsFidlMessageValue() const { return nullptr; }

  // Returns true if we need to load information about the handle (call to zx_object_get_info with
  // ZX_INFO_HANDLE_TABLE). We need to load information about the handle if one of the handles of
  // the value has an unknown koid.
  virtual bool NeedsToLoadHandleInfo(int64_t timestamp, zx_koid_t tid,
                                     semantic::HandleSemantic* handle_semantic) const {
    return false;
  }

  // Returns the size needed to display the value. If the needed size is
  // greater than |remaining_size|, the return value can be anything greater
  // than |remaining_size| and the only useful information is that the value
  // can't fit in |remaining_size|.
  // Remaining size is just an optimization parameter. It avoids to compute the
  // whole display size for an object: the computation is stopped as soon as we
  // find that the object doesn't fit.
  virtual size_t DisplaySize(const Type* for_type, size_t remaining_size) const = 0;

  // Pretty print of the value.
  virtual void PrettyPrint(const Type* for_type, PrettyPrinter& printer) const = 0;

  // Use a visitor on this value;
  virtual void Visit(Visitor* visitor, const Type* for_type) const = 0;
};

// An invalid value. This value can't be present in a valid object.
// It can only be found if we had an error while decoding a message.
class InvalidValue : public Value {
 public:
  InvalidValue() = default;

  size_t DisplaySize(const Type* for_type, size_t remaining_size) const override {
    constexpr int kInvalidSize = 7;
    return kInvalidSize;  // length of "invalid"
  }

  void PrettyPrint(const Type* for_type, PrettyPrinter& printer) const override {
    printer << Red << "invalid" << ResetColor;
  }

  void Visit(Visitor* visitor, const Type* for_type) const override;
};

// A null value.
class NullValue : public Value {
 public:
  NullValue() = default;

  bool IsNull() const override { return true; }

  size_t DisplaySize(const Type* for_type, size_t remaining_size) const override {
    constexpr int kNullSize = 4;
    return kNullSize;  // length of "null"
  }

  void PrettyPrint(const Type* for_type, PrettyPrinter& printer) const override {
    printer << Red << "null" << ResetColor;
  }

  void Visit(Visitor* visitor, const Type* for_type) const override;
};

// A value with no known representation (we only print the raw data).
class RawValue : public Value {
 public:
  RawValue(const uint8_t* data, size_t size) : data_(data, data + size) {}

  const std::vector<uint8_t>& data() const { return data_; }

  size_t DisplaySize(const Type* for_type, size_t remaining_size) const override;

  void PrettyPrint(const Type* for_type, PrettyPrinter& printer) const override;

  void Visit(Visitor* visitor, const Type* for_type) const override;

 private:
  const std::vector<uint8_t> data_;
};

// A Boolean value.
class BoolValue : public Value {
 public:
  explicit BoolValue(uint8_t value) : value_(value) {}

  uint8_t value() const { return value_; }

  size_t DisplaySize(const Type* for_type, size_t remaining_size) const override;

  void PrettyPrint(const Type* for_type, PrettyPrinter& printer) const override;

  void Visit(Visitor* visitor, const Type* for_type) const override;

 private:
  const uint8_t value_;
};

class IntegerValue : public Value {
 public:
  IntegerValue(uint64_t absolute_value, bool negative)
      : absolute_value_(absolute_value), negative_(negative) {}
  explicit IntegerValue(int64_t value)
      : absolute_value_((value < 0) ? -static_cast<uint64_t>(value) : value),
        negative_(value < 0) {}
  explicit IntegerValue(uint64_t value) : absolute_value_(value), negative_(false) {}

  uint64_t absolute_value() const { return absolute_value_; }
  bool negative() const { return negative_; }

  uint8_t GetUint8Value() const override;

  bool GetIntegerValue(uint64_t* absolute, bool* negative) const override {
    *absolute = absolute_value_;
    *negative = negative_;
    return true;
  }

  bool GetDoubleValue(double* result) const override {
    *result = static_cast<double>(absolute_value_);
    if (negative_) {
      *result = -(*result);
    }
    return true;
  }

  size_t DisplaySize(const Type* for_type, size_t remaining_size) const override;

  void PrettyPrint(const Type* for_type, PrettyPrinter& printer) const override;

  void Visit(Visitor* visitor, const Type* for_type) const override;

 private:
  const uint64_t absolute_value_;
  const bool negative_;
};

class DoubleValue : public Value {
 public:
  explicit DoubleValue(double value) : value_(value) {}

  double value() const { return value_; }

  bool GetIntegerValue(uint64_t* absolute, bool* negative) const override {
    if (value_ < 0) {
      *absolute = static_cast<uint64_t>(-value_);
      *negative = true;
    } else {
      *absolute = static_cast<uint64_t>(value_);
      *negative = false;
    }
    return true;
  }

  bool GetDoubleValue(double* result) const override {
    *result = value_;
    return true;
  }

  size_t DisplaySize(const Type* for_type, size_t remaining_size) const override;

  void PrettyPrint(const Type* for_type, PrettyPrinter& printer) const override;

  void Visit(Visitor* visitor, const Type* for_type) const override;

 private:
  const double value_;
};

// A string value.
class StringValue : public Value {
 public:
  explicit StringValue(std::string_view string) : string_(string) {}

  const std::string& string() const { return string_; }

  const StringValue* AsStringValue() const override { return this; }

  size_t DisplaySize(const Type* for_type, size_t remaining_size) const override;

  void PrettyPrint(const Type* for_type, PrettyPrinter& printer) const override;

  void Visit(Visitor* visitor, const Type* for_type) const override;

 private:
  const std::string string_;
};

// A handle.
class HandleValue : public Value {
 public:
  explicit HandleValue(const zx_handle_disposition_t& handle) : handle_(handle) {}

  const zx_handle_disposition_t& handle() const { return handle_; }

  const HandleValue* AsHandleValue() const override { return this; }

  bool NeedsToLoadHandleInfo(int64_t timestamp, zx_koid_t tid,
                             semantic::HandleSemantic* handle_semantic) const override;

  size_t DisplaySize(const Type* for_type, size_t remaining_size) const override;

  void PrettyPrint(const Type* for_type, PrettyPrinter& printer) const override;

  void Visit(Visitor* visitor, const Type* for_type) const override;

 private:
  const zx_handle_disposition_t handle_;
};

// An union.
class UnionValue : public Value {
 public:
  UnionValue(const UnionMember& member, std::unique_ptr<Value> value)
      : member_(member), value_(std::move(value)) {}

  const UnionMember& member() const { return member_; }
  const std::unique_ptr<Value>& value() const { return value_; }

  bool NeedsToLoadHandleInfo(int64_t timestamp, zx_koid_t tid,
                             semantic::HandleSemantic* handle_semantic) const override;

  size_t DisplaySize(const Type* for_type, size_t remaining_size) const override;

  void PrettyPrint(const Type* for_type, PrettyPrinter& printer) const override;

  void Visit(Visitor* visitor, const Type* for_type) const override;

 private:
  const UnionMember& member_;
  const std::unique_ptr<Value> value_;
};

// An instance of a Struct. This includes requests and responses which are also structs.
class StructValue : public Value {
 public:
  explicit StructValue(const Struct& struct_definition) : struct_definition_(struct_definition) {}

  const Struct& struct_definition() const { return struct_definition_; }
  const std::map<const StructMember*, std::unique_ptr<Value>>& fields() const { return fields_; }

  void AddField(const StructMember* member, std::unique_ptr<Value> value) {
    fields_.emplace(std::make_pair(member, std::move(value)));
  }

  void inline AddField(std::string_view name, std::unique_ptr<Value> value) {
    AddField(name, 0, std::move(value));
  }

  void AddField(std::string_view name, uint32_t id, std::unique_ptr<Value> value);

  StructValue* AsStructValue() override { return this; }
  const StructValue* AsStructValue() const override { return this; }

  std::pair<const Type*, const Value*> GetFieldValue(std::string_view field_name) const;

  bool NeedsToLoadHandleInfo(int64_t timestamp, zx_koid_t tid,
                             semantic::HandleSemantic* handle_semantic) const override;

  size_t DisplaySize(const Type* for_type, size_t remaining_size) const override;

  void PrettyPrint(const Type* for_type, PrettyPrinter& printer) const override;

  void Visit(Visitor* visitor, const Type* for_type) const override;

  // Extract the JSON for this object.
  void ExtractJson(rapidjson::Document::AllocatorType& allocator, rapidjson::Value& result) const;

 private:
  const Struct& struct_definition_;
  std::map<const StructMember*, std::unique_ptr<Value>> fields_;
};

// A vector.
class VectorValue : public Value {
 public:
  VectorValue() = default;

  const std::vector<std::unique_ptr<Value>>& values() const { return values_; }

  void AddValue(std::unique_ptr<Value> value) {
    if (value == nullptr) {
      is_string_ = false;
    } else {
      uint8_t uvalue = value->GetUint8Value();
      if (!std::isprint(uvalue)) {
        if ((uvalue == '\r') || (uvalue == '\n')) {
          has_new_line_ = true;
        } else {
          is_string_ = false;
        }
      }
    }
    values_.push_back(std::move(value));
  }

  const VectorValue* AsVectorValue() const override { return this; }

  bool NeedsToLoadHandleInfo(int64_t timestamp, zx_koid_t tid,
                             semantic::HandleSemantic* handle_semantic) const override;

  size_t DisplaySize(const Type* for_type, size_t remaining_size) const override;

  void PrettyPrint(const Type* for_type, PrettyPrinter& printer) const override;

  void Visit(Visitor* visitor, const Type* for_type) const override;

 private:
  std::vector<std::unique_ptr<Value>> values_;
  bool is_string_ = true;
  bool has_new_line_ = false;
};

// A table.
class TableValue : public Value {
 public:
  explicit TableValue(const Table& table_definition) : table_definition_(table_definition) {}

  const Table& table_definition() const { return table_definition_; }
  const std::map<const TableMember*, std::unique_ptr<Value>>& members() const { return members_; }
  Ordinal32 highest_member() const { return highest_member_; }

  void AddMember(const TableMember* member, std::unique_ptr<Value> value) {
    members_.emplace(std::make_pair(member, std::move(value)));
    if (member->ordinal() > highest_member_) {
      highest_member_ = member->ordinal();
    }
  }

  bool AddMember(std::string_view name, std::unique_ptr<Value> value);

  bool NeedsToLoadHandleInfo(int64_t timestamp, zx_koid_t tid,
                             semantic::HandleSemantic* handle_semantic) const override;

  size_t DisplaySize(const Type* for_type, size_t remaining_size) const override;

  void PrettyPrint(const Type* for_type, PrettyPrinter& printer) const override;

  void Visit(Visitor* visitor, const Type* for_type) const override;

 private:
  const Table& table_definition_;
  std::map<const TableMember*, std::unique_ptr<Value>> members_;
  Ordinal32 highest_member_ = 0;
};

// An instance of a FIDL message.
class FidlMessageValue : public Value {
 public:
  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);
  FidlMessageValue(zx_txid_t txid, uint64_t ordinal, const std::string& global_errors,
                   const std::string& epitaph_error, bool received, bool is_request,
                   bool unknown_direction, const fidl_codec::InterfaceMethod* method,
                   const uint8_t* bytes, size_t byte_size, const std::string& request_errors,
                   const std::string& response_errors)
      : txid_(txid),
        ordinal_(ordinal),
        global_errors_(global_errors),
        epitaph_error_(epitaph_error),
        received_(received),
        is_request_(is_request),
        unknown_direction_(unknown_direction),
        method_(method),
        bytes_(bytes, bytes + byte_size),
        request_errors_(request_errors),
        response_errors_(response_errors) {}

  zx_txid_t txid() const { return txid_; }
  uint64_t ordinal() const { return ordinal_; }
  const std::string& global_errors() const { return global_errors_; }
  const std::string& epitaph_error() const { return epitaph_error_; }
  bool received() const { return received_; }
  bool is_request() const { return is_request_; }
  bool unknown_direction() const { return unknown_direction_; }
  const fidl_codec::InterfaceMethod* method() const { return method_; }
  const std::vector<uint8_t>& bytes() const { return bytes_; }
  const std::vector<zx_handle_disposition_t>& handles() const { return handles_; }
  void add_handle(const zx_handle_disposition_t& handle) { handles_.emplace_back(handle); }
  const StructValue* decoded_request() const { return decoded_request_.get(); }
  void set_decoded_request(std::unique_ptr<StructValue> decoded_request) {
    decoded_request_ = std::move(decoded_request);
  }
  const std::string& request_errors() const { return request_errors_; }
  const StructValue* decoded_response() const { return decoded_response_.get(); }
  void set_decoded_response(std::unique_ptr<StructValue> decoded_response) {
    decoded_response_ = std::move(decoded_response);
  }
  const std::string& response_errors() const { return response_errors_; }
  bool matched_request() const { return (decoded_request_ != nullptr) && request_errors_.empty(); }
  bool matched_response() const {
    return (decoded_response_ != nullptr) && response_errors_.empty();
  }

  const FidlMessageValue* AsFidlMessageValue() const override { return this; }

  bool NeedsToLoadHandleInfo(int64_t timestamp, zx_koid_t tid,
                             semantic::HandleSemantic* handle_semantic) const override;

  size_t DisplaySize(const Type* for_type, size_t remaining_size) const override;

  void PrettyPrint(const Type* for_type, PrettyPrinter& printer) const override;

  void PrintMessage(PrettyPrinter& printer) const;

  void PrintMessageBody(PrettyPrinter& printer) const;

  void DumpMessage(PrettyPrinter& printer) const;

  void Visit(Visitor* visitor, const Type* for_type) const override;

 private:
  // The transfer ID of the mesage.
  const zx_txid_t txid_;
  // The ordinal of the message.
  const uint64_t ordinal_;
  // Global errors for the message (errors before we can start decoding anything).
  const std::string global_errors_;
  // Text value of the error status of the epitaph.
  const std::string epitaph_error_;
  // True if the message was received.
  const bool received_;
  // True if the message is a request. False if the message is a response.
  const bool is_request_;
  // True if we haven't been able to select a request of a response (case where both can be
  // decoded).
  const bool unknown_direction_;
  // The method associated with the ordinal.
  const fidl_codec::InterfaceMethod* const method_;
  // All the bytes of the message.
  std::vector<uint8_t> bytes_;
  // All the handles of the message.
  std::vector<zx_handle_disposition_t> handles_;
  // Value of the request we have been able to decode.
  std::unique_ptr<StructValue> decoded_request_;
  // Errors generated during the decoding of the request. If not empty, decoded_request_ holds only
  // a partial result.
  const std::string request_errors_;
  // Value of the response we have been able to decode.
  std::unique_ptr<StructValue> decoded_response_;
  // Errors generated during the decoding of the response. If not empty, decoded_response_ holds
  // only a partial result.
  const std::string response_errors_;
};

}  // namespace fidl_codec

#endif  // SRC_LIB_FIDL_CODEC_WIRE_OBJECT_H_
