// Part of the Crubit project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include "rs_bindings_from_cc/ir.h"

#include <stdint.h>

#include <optional>
#include <ostream>
#include <string>
#include <utility>
#include <variant>
#include <vector>

#include "base/integral_types.h"
#include "rs_bindings_from_cc/bazel_types.h"
#include "third_party/absl/strings/string_view.h"
#include "third_party/json/src/json.hpp"
#include "util/intops/strong_int.h"

namespace rs_bindings_from_cc {

template <class T>
static std::vector<nlohmann::json> VectorToJson(const std::vector<T>& v) {
  std::vector<nlohmann::json> result;
  result.reserve(v.size());
  for (const T& t : v) {
    result.push_back(t.ToJson());
  }
  return result;
}

nlohmann::json HeaderName::ToJson() const {
  nlohmann::json result;
  result["name"] = name_;
  return result;
}

nlohmann::json Lifetime::ToJson() const {
  nlohmann::json result;
  result["name"] = name;
  result["id"] = id.value();
  return result;
}

nlohmann::json RsType::ToJson() const {
  nlohmann::json result;

  if (decl_id.has_value()) {
    result["decl_id"] = decl_id->value();
  } else {
    result["name"] = name;
  }
  std::vector<nlohmann::json> json_lifetime_args;
  json_lifetime_args.reserve(lifetime_args.size());
  for (const LifetimeId& lifetime_id : lifetime_args) {
    json_lifetime_args.push_back(lifetime_id.value());
  }
  result["lifetime_args"] = json_lifetime_args;
  result["type_args"] = VectorToJson(type_args);

  return result;
}

nlohmann::json CcType::ToJson() const {
  nlohmann::json result;

  if (decl_id.has_value()) {
    result["decl_id"] = decl_id->value();
  } else {
    result["name"] = name;
  }
  result["is_const"] = is_const;
  result["type_args"] = VectorToJson(type_args);

  return result;
}

MappedType MappedType::PointerTo(MappedType pointee_type,
                                 std::optional<LifetimeId> lifetime,
                                 bool nullable) {
  absl::string_view rs_name;
  bool has_lifetime = lifetime.has_value();
  if (has_lifetime) {
    rs_name = pointee_type.cc_type.is_const ? internal::kRustRefConst
                                            : internal::kRustRefMut;
  } else {
    rs_name = pointee_type.cc_type.is_const ? internal::kRustPtrConst
                                            : internal::kRustPtrMut;
  }
  auto pointer_type =
      Simple(std::string(rs_name), std::string(internal::kCcPtr));
  if (has_lifetime) {
    pointer_type.rs_type.lifetime_args.push_back(*std::move(lifetime));
  }
  pointer_type.rs_type.type_args.push_back(std::move(pointee_type.rs_type));
  if (has_lifetime && nullable) {
    pointer_type.rs_type =
        RsType{.name = "Option", .type_args = {pointer_type.rs_type}};
  }
  pointer_type.cc_type.type_args.push_back(std::move(pointee_type.cc_type));
  return pointer_type;
}

MappedType MappedType::LValueReferenceTo(MappedType pointee_type,
                                         std::optional<LifetimeId> lifetime) {
  absl::string_view rs_name;
  if (lifetime.has_value()) {
    rs_name = pointee_type.cc_type.is_const ? internal::kRustRefConst
                                            : internal::kRustRefMut;
  } else {
    rs_name = pointee_type.cc_type.is_const ? internal::kRustPtrConst
                                            : internal::kRustPtrMut;
  }
  auto reference_type =
      Simple(std::string(rs_name), std::string(internal::kCcLValueRef));
  if (lifetime.has_value()) {
    reference_type.rs_type.lifetime_args.push_back(*std::move(lifetime));
  }
  reference_type.rs_type.type_args.push_back(std::move(pointee_type.rs_type));
  reference_type.cc_type.type_args.push_back(std::move(pointee_type.cc_type));
  return reference_type;
}

MappedType MappedType::FuncPtr(absl::string_view cc_call_conv,
                               absl::string_view rs_abi,
                               std::optional<LifetimeId> lifetime,
                               MappedType return_type,
                               std::vector<MappedType> param_types) {
  std::vector<MappedType> type_args = std::move(param_types);
  type_args.push_back(std::move(return_type));

  std::vector<CcType> cc_type_args;
  std::vector<RsType> rs_type_args;
  cc_type_args.reserve(type_args.size());
  rs_type_args.reserve(type_args.size());
  for (MappedType& type_arg : type_args) {
    cc_type_args.push_back(std::move(type_arg.cc_type));
    rs_type_args.push_back(std::move(type_arg.rs_type));
  }

  CcType cc_func_value_type = CcType{
      .name = absl::StrCat(internal::kCcFuncValue, " ", cc_call_conv),
      .type_args = std::move(cc_type_args),
  };
  CcType cc_func_ptr_type = CcType{.name = std::string(internal::kCcPtr),
                                   .type_args = {cc_func_value_type}};

  // Rust cannot express a function *value* type, only function pointer types.
  RsType rs_func_ptr_type = RsType{
      .name = absl::StrCat(internal::kRustFuncPtr, " ", rs_abi),
      .type_args = std::move(rs_type_args),
  };
  if (lifetime.has_value())
    rs_func_ptr_type.lifetime_args.push_back(*std::move(lifetime));

  // `fn() -> ()` is a *non-nullable* pointer in Rust. Since function pointers
  // in C++ *can* be null, we need to wrap Rust's function pointer in
  // `Option<...>`.
  RsType rs_option_type =
      RsType{.name = "Option", .type_args = {rs_func_ptr_type}};

  return MappedType{
      .rs_type = std::move(rs_option_type),
      .cc_type = std::move(cc_func_ptr_type),
  };
}

nlohmann::json MappedType::ToJson() const {
  nlohmann::json result;

  result["rs_type"] = rs_type.ToJson();
  result["cc_type"] = cc_type.ToJson();

  return result;
}

nlohmann::json Identifier::ToJson() const {
  nlohmann::json result;
  result["identifier"] = identifier_;
  return result;
}

nlohmann::json IntegerConstant::ToJson() const {
  nlohmann::json result;
  result["is_negative"] = is_negative_;
  result["wrapped_value"] = wrapped_value_;
  return result;
}

nlohmann::json Operator::ToJson() const {
  nlohmann::json result;
  result["name"] = name_;
  return result;
}

static std::string SpecialNameToString(SpecialName special_name) {
  switch (special_name) {
    case SpecialName::kDestructor:
      return "Destructor";
    case SpecialName::kConstructor:
      return "Constructor";
  }
}

nlohmann::json ToJson(const UnqualifiedIdentifier& unqualified_identifier) {
  nlohmann::json result;
  if (auto* id = std::get_if<Identifier>(&unqualified_identifier)) {
    result["Identifier"] = id->ToJson();
  } else if (auto* op = std::get_if<Operator>(&unqualified_identifier)) {
    result["Operator"] = op->ToJson();
  } else {
    SpecialName special_name = std::get<SpecialName>(unqualified_identifier);
    result[SpecialNameToString(special_name)] = nullptr;
  }
  return result;
}

nlohmann::json FuncParam::ToJson() const {
  nlohmann::json result;
  result["type"] = type.ToJson();
  result["identifier"] = identifier.ToJson();
  return result;
}

std::ostream& operator<<(std::ostream& o, const SpecialName& special_name) {
  return o << SpecialNameToString(special_name);
}

nlohmann::json MemberFuncMetadata::ToJson() const {
  nlohmann::json meta;

  meta["record_id"] = record_id.value();

  if (instance_method_metadata.has_value()) {
    nlohmann::json instance;

    absl::string_view reference;
    switch (instance_method_metadata->reference) {
      case MemberFuncMetadata::kLValue:
        reference = "LValue";
        break;
      case MemberFuncMetadata::kRValue:
        reference = "RValue";
        break;
      case MemberFuncMetadata::kUnqualified:
        reference = "Unqualified";
        break;
    }
    instance["reference"] = reference;
    instance["is_const"] = instance_method_metadata->is_const;
    instance["is_virtual"] = instance_method_metadata->is_virtual;
    instance["is_explicit_ctor"] = instance_method_metadata->is_explicit_ctor;

    meta["instance_method_metadata"] = std::move(instance);
  }

  return meta;
}

nlohmann::json Func::ToJson() const {
  nlohmann::json func;
  func["name"] = rs_bindings_from_cc::ToJson(name);
  func["owning_target"] = owning_target.value();
  if (doc_comment) {
    func["doc_comment"] = *doc_comment;
  }
  func["mangled_name"] = mangled_name;
  func["return_type"] = return_type.ToJson();
  func["params"] = VectorToJson(params);
  func["lifetime_params"] = VectorToJson(lifetime_params);
  func["is_inline"] = is_inline;
  if (member_func_metadata.has_value()) {
    func["member_func_metadata"] = member_func_metadata->ToJson();
  }
  func["source_loc"] = source_loc.ToJson();

  nlohmann::json item;
  item["Func"] = std::move(func);
  return item;
}

static std::string AccessToString(AccessSpecifier access) {
  switch (access) {
    case kPublic:
      return "Public";
    case kProtected:
      return "Protected";
    case kPrivate:
      return "Private";
  }
}

std::ostream& operator<<(std::ostream& o, const AccessSpecifier& access) {
  return o << AccessToString(access);
}

nlohmann::json Field::ToJson() const {
  nlohmann::json result;

  result["identifier"] = identifier.ToJson();
  if (doc_comment) {
    result["doc_comment"] = *doc_comment;
  }
  result["type"] = type.ToJson();
  result["access"] = AccessToString(access);
  result["offset"] = offset;
  result["is_no_unique_address"] = is_no_unique_address;
  return result;
}

static std::string SpecialMemberDefinitionToString(
    SpecialMemberFunc::Definition def) {
  switch (def) {
    case SpecialMemberFunc::Definition::kTrivial:
      return "Trivial";
    case SpecialMemberFunc::Definition::kNontrivialMembers:
      return "NontrivialMembers";
    case SpecialMemberFunc::Definition::kNontrivialUserDefined:
      return "NontrivialUserDefined";
    case SpecialMemberFunc::Definition::kDeleted:
      return "Deleted";
  }
}

std::ostream& operator<<(std::ostream& o,
                         const SpecialMemberFunc::Definition& definition) {
  return o << SpecialMemberDefinitionToString(definition);
}

nlohmann::json SpecialMemberFunc::ToJson() const {
  nlohmann::json result;
  result["definition"] = SpecialMemberDefinitionToString(definition);
  result["access"] = AccessToString(access);
  return result;
}

nlohmann::json BaseClass::ToJson() const {
  nlohmann::json base;
  base["base_record_id"] = base_record_id.value();
  if (offset.has_value()) {
    base["offset"] = *offset;
  }
  return base;
}
nlohmann::json Record::ToJson() const {
  nlohmann::json record;
  record["identifier"] = identifier.ToJson();
  record["id"] = id.value();
  record["owning_target"] = owning_target.value();
  if (doc_comment) {
    record["doc_comment"] = *doc_comment;
  }
  record["unambiguous_public_bases"] = VectorToJson(unambiguous_public_bases);
  record["fields"] = VectorToJson(fields);
  record["lifetime_params"] = VectorToJson(lifetime_params);
  record["size"] = size;
  record["alignment"] = alignment;
  if (base_size) {
    record["base_size"] = *base_size;
  }
  record["override_alignment"] = override_alignment;
  record["copy_constructor"] = copy_constructor.ToJson();
  record["move_constructor"] = move_constructor.ToJson();
  record["destructor"] = destructor.ToJson();
  record["is_trivial_abi"] = is_trivial_abi;
  record["is_final"] = is_final;

  nlohmann::json item;
  item["Record"] = std::move(record);
  return item;
}

nlohmann::json Enumerator::ToJson() const {
  nlohmann::json result;
  result["identifier"] = identifier.ToJson();
  result["value"] = value.ToJson();
  return result;
}

nlohmann::json Enum::ToJson() const {
  nlohmann::json enum_ir;
  enum_ir["identifier"] = identifier.ToJson();
  enum_ir["id"] = id.value();
  enum_ir["owning_target"] = owning_target.value();
  enum_ir["underlying_type"] = underlying_type.ToJson();
  enum_ir["enumerators"] = VectorToJson(enumerators);

  nlohmann::json item;
  item["Enum"] = std::move(enum_ir);
  return item;
}

nlohmann::json TypeAlias::ToJson() const {
  nlohmann::json type_alias;
  type_alias["identifier"] = identifier.ToJson();
  type_alias["id"] = id.value();
  type_alias["owning_target"] = owning_target.value();
  type_alias["underlying_type"] = underlying_type.ToJson();

  nlohmann::json item;
  item["TypeAlias"] = std::move(type_alias);
  return item;
}

nlohmann::json SourceLoc::ToJson() const {
  nlohmann::json source_loc;
  source_loc["filename"] = filename;
  source_loc["line"] = line;
  source_loc["column"] = column;
  return source_loc;
}

nlohmann::json UnsupportedItem::ToJson() const {
  nlohmann::json unsupported;
  unsupported["name"] = name;
  unsupported["message"] = message;
  unsupported["source_loc"] = source_loc.ToJson();

  nlohmann::json item;
  item["UnsupportedItem"] = std::move(unsupported);
  return item;
}

nlohmann::json Comment::ToJson() const {
  nlohmann::json comment;
  comment["text"] = text;

  nlohmann::json item;
  item["Comment"] = std::move(comment);
  return item;
}

nlohmann::json IR::ToJson() const {
  std::vector<nlohmann::json> json_items;
  json_items.reserve(items.size());
  for (const auto& item : items) {
    std::visit([&](auto&& item) { json_items.push_back(item.ToJson()); }, item);
  }

  nlohmann::json result;
  result["used_headers"] = VectorToJson(used_headers);
  result["current_target"] = current_target.value();
  result["items"] = std::move(json_items);
  return result;
}

}  // namespace rs_bindings_from_cc
