// Copyright 2020 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_DEVELOPER_SHELL_COMMON_RESULT_H_
#define SRC_DEVELOPER_SHELL_COMMON_RESULT_H_

#include <lib/fidl/llcpp/vector_view.h>

#include <cstdint>
#include <map>
#include <memory>
#include <ostream>
#include <sstream>
#include <string>
#include <vector>

#include "fuchsia/shell/llcpp/fidl.h"

namespace shell::common {

// Base class for all the types.
class ResultType {
 public:
  ResultType() = default;
  virtual ~ResultType() = default;

  // Dumps the type.
  virtual void Dump(std::ostream& os, const char* separator) const {}
};

class ResultTypeUint64 : public ResultType {
 public:
  ResultTypeUint64() = default;

  void Dump(std::ostream& os, const char* separator) const override { os << separator << "uint64"; }
};

class ResultTypeString : public ResultType {
 public:
  ResultTypeString() = default;

  void Dump(std::ostream& os, const char* separator) const override { os << separator << "string"; }
};

// Defines a field for a result object schema.
class ResultSchemaField {
 public:
  ResultSchemaField(uint64_t node_id, const fidl::StringView& name,
                    std::unique_ptr<ResultType> type)
      : node_id_(node_id), name_(name.data(), name.size()), type_(std::move(type)) {}

  uint64_t node_id() const { return node_id_; }
  const std::string& name() const { return name_; }
  const ResultType* type() const { return type_.get(); }

 private:
  const uint64_t node_id_;
  const std::string name_;
  std::unique_ptr<ResultType> type_;
};

// Defines an object shema for a result.
class ResultSchema {
 public:
  ResultSchema() = default;

  void AddField(uint64_t node_id, const fidl::StringView& name, std::unique_ptr<ResultType> type) {
    fields_.emplace_back(std::make_shared<ResultSchemaField>(node_id, name, std::move(type)));
  }

  std::shared_ptr<ResultSchemaField> SearchField(uint64_t field_id) const {
    for (const auto& field : fields_) {
      if (field->node_id() == field_id) {
        return field;
      }
    }
    return nullptr;
  }

 private:
  std::vector<std::shared_ptr<ResultSchemaField>> fields_;
};

// Defines an object type for a result.
class ResultTypeObject : public ResultType {
 public:
  ResultTypeObject(std::shared_ptr<ResultSchema> schema) : schema_(schema) {}

 private:
  std::shared_ptr<ResultSchema> schema_;
};

// Base class for a result.
class ResultNode {
 public:
  ResultNode() = default;
  virtual ~ResultNode() = default;

  // Dumps the result.
  virtual void Dump(std::ostream& os) const = 0;
};

// Defines an integer literal result.
class ResultNodeIntegerLiteral : public ResultNode {
 public:
  ResultNodeIntegerLiteral(const fidl::VectorView<uint64_t>& absolute_value, bool negative)
      : negative_(negative) {
    for (auto value : absolute_value) {
      absolute_value_.push_back(value);
    }
  }

  void Dump(std::ostream& os) const override {
    if (negative_) {
      os << '-';
    }
    if (absolute_value_.empty()) {
      os << '0';
    } else if (absolute_value_.size() == 1) {
      os << absolute_value_[0];
    } else {
      os << "???";
    }
  }

 private:
  std::vector<uint64_t> absolute_value_;
  const bool negative_;
};

// Define a string literal result.
class ResultNodeStringLiteral : public ResultNode {
 public:
  ResultNodeStringLiteral(const fidl::StringView& string) : string_(string.data(), string.size()) {}

  void Dump(std::ostream& os) const override { os << '"' << string_ << '"'; }

 private:
  const std::string string_;
};

// Defines a field for an object result.
class ResultNodeObjectField {
 public:
  ResultNodeObjectField(std::shared_ptr<ResultSchemaField> field, std::unique_ptr<ResultNode> value)
      : field_(field), value_(std::move(value)) {}

  void Dump(std::ostream& os) const {
    os << field_->name();
    if (field_->type() != nullptr) {
      field_->type()->Dump(os, ": ");
    }
    os << " = ";
    value_->Dump(os);
  }

 private:
  std::shared_ptr<ResultSchemaField> field_;
  std::unique_ptr<ResultNode> value_;
};

// Defines an object result.
class ResultNodeObject : public ResultNode {
 public:
  ResultNodeObject(std::shared_ptr<ResultSchema> schema) : schema_(schema) {}

  void AddField(std::shared_ptr<ResultSchemaField> field, std::unique_ptr<ResultNode> value) {
    fields_.emplace_back(std::make_unique<ResultNodeObjectField>(field, std::move(value)));
  }

  void Dump(std::ostream& os) const override {
    os << '{';
    const char* separator = "";
    for (const auto& field : fields_) {
      os << separator;
      field->Dump(os);
      separator = ", ";
    }
    os << '}';
  }

 private:
  std::shared_ptr<ResultSchema> schema_;
  std::vector<std::unique_ptr<ResultNodeObjectField>> fields_;
};

// Helper for a result deserialization from a vector of nodes.
class DeserializeResult {
 public:
  DeserializeResult() = default;

  // Deserializes a result from a vector of nodes.
  std::unique_ptr<ResultNode> Deserialize(
      const fidl::VectorView<llcpp::fuchsia::shell::Node>& nodes);

  // Deserializes a node (value).
  std::unique_ptr<ResultNode> DeserializeNode(
      const fidl::VectorView<llcpp::fuchsia::shell::Node>& nodes, uint64_t node_id);

  // Deserializes an object schema.
  std::shared_ptr<ResultSchema> DeserializeSchema(
      const fidl::VectorView<llcpp::fuchsia::shell::Node>& nodes, uint64_t node_id);

  // Deserializes a type.
  std::unique_ptr<ResultType> DeserializeType(
      const fidl::VectorView<llcpp::fuchsia::shell::Node>& nodes,
      const llcpp::fuchsia::shell::ShellType& shell_type);

 private:
  // All the schema which have already been deserialized.
  std::map<uint64_t, std::shared_ptr<ResultSchema>> schemas_;
};

}  // namespace shell::common

#endif  // SRC_DEVELOPER_SHELL_COMMON_RESULT_H_
