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

#include "src/developer/shell/common/result.h"

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

#include <ostream>

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

namespace shell::common {

std::unique_ptr<ResultNode> DeserializeResult::Deserialize(
    const fidl::VectorView<llcpp::fuchsia::shell::Node>& nodes) {
  FX_DCHECK(!nodes.empty());
  return DeserializeNode(nodes, nodes.count());
}

std::unique_ptr<ResultNode> DeserializeResult::DeserializeNode(
    const fidl::VectorView<llcpp::fuchsia::shell::Node>& nodes, uint64_t node_id) {
  FX_DCHECK(node_id <= nodes.count());
  const llcpp::fuchsia::shell::Node& node = nodes[node_id - 1];
  if (node.is_integer_literal()) {
    return std::make_unique<ResultNodeIntegerLiteral>(node.integer_literal().absolute_value,
                                                      node.integer_literal().negative);
  }
  if (node.is_string_literal()) {
    return std::make_unique<ResultNodeStringLiteral>(node.string_literal());
  }
  if (node.is_object()) {
    auto schema = DeserializeSchema(nodes, node.object().object_schema.node_id);
    if (schema != nullptr) {
      auto result = std::make_unique<ResultNodeObject>(schema);
      for (const auto& field_id : node.object().fields) {
        FX_DCHECK(field_id.file_id == 1U);
        FX_DCHECK(field_id.node_id <= nodes.count());
        const llcpp::fuchsia::shell::Node& field_node = nodes[field_id.node_id - 1];
        FX_DCHECK(field_node.is_object_field());
        FX_DCHECK(field_node.object_field().object_field_schema.file_id == 1U);
        auto field_schema =
            schema->SearchField(field_node.object_field().object_field_schema.node_id);
        FX_DCHECK(field_schema != nullptr);
        auto field_value = DeserializeNode(nodes, field_node.object_field().value.node_id);
        if (field_value != nullptr) {
          result->AddField(field_schema, std::move(field_value));
        }
      }
      return result;
    }
  }
  return nullptr;
}

std::shared_ptr<ResultSchema> DeserializeResult::DeserializeSchema(
    const fidl::VectorView<llcpp::fuchsia::shell::Node>& nodes, uint64_t node_id) {
  if (node_id == 0) {
    return nullptr;
  }
  auto schema = schemas_.find(node_id);
  if (schema != schemas_.end()) {
    return schema->second;
  }
  FX_DCHECK(node_id <= nodes.count());
  const llcpp::fuchsia::shell::Node& schema_node = nodes[node_id - 1];
  if (!schema_node.is_object_schema()) {
    return nullptr;
  }
  auto result = std::make_shared<ResultSchema>();
  schemas_.emplace(std::pair(node_id, result));
  for (const auto& field : schema_node.object_schema().fields) {
    FX_DCHECK(field.file_id == 1U);
    uint64_t field_id = field.node_id;
    FX_DCHECK(field_id <= nodes.count());
    const llcpp::fuchsia::shell::Node& schema_field_node = nodes[field_id - 1];
    if (schema_field_node.is_field_schema()) {
      result->AddField(field_id, schema_field_node.field_schema().name,
                       DeserializeType(nodes, schema_field_node.field_schema().type));
    }
  }
  return result;
}

std::unique_ptr<ResultType> DeserializeResult::DeserializeType(
    const fidl::VectorView<llcpp::fuchsia::shell::Node>& nodes,
    const llcpp::fuchsia::shell::ShellType& shell_type) {
  if (shell_type.is_builtin_type()) {
    switch (shell_type.builtin_type()) {
      case llcpp::fuchsia::shell::BuiltinType::UINT64:
        return std::make_unique<ResultTypeUint64>();
      case llcpp::fuchsia::shell::BuiltinType::STRING:
        return std::make_unique<ResultTypeString>();
      default:
        return nullptr;
    }
  }
  return nullptr;
}

}  // namespace shell::common
