// 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 <memory>
#include <optional>
#include <ostream>
#include <string>
#include <utility>
#include <variant>
#include <vector>

#include "absl/base/nullability.h"
#include "absl/log/check.h"
#include "absl/status/status.h"
#include "absl/strings/cord.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "common/string_type.h"
#include "common/strong_int.h"
#include "llvm/Support/JSON.h"

namespace crubit {
namespace {
// https://en.cppreference.com/w/cpp/utility/variant/visit
template <typename... Ts>
struct visitor : Ts... {
  using Ts::operator()...;
};
}  // namespace

template <class T>
llvm::json::Value toJSON(const T& t) {
  return t.ToJson();
}

template <typename TTag, typename TInt>
llvm::json::Value toJSON(const crubit::StrongInt<TTag, TInt> strong_int) {
  return llvm::json::Value(strong_int.value());
}

template <typename TTag>
llvm::json::Value toJSON(const crubit::StringType<TTag> string_type) {
  return llvm::json::Value(string_type.value());
}

template <class T>
llvm::json::Value toJSON(const absl::StatusOr<T>& t) {
  if (t.ok()) {
    return llvm::json::Object{{"Ok", *t}};
  }
  return llvm::json::Object{{"Err", std::string(t.status().message())}};
}

llvm::json::Value HeaderName::ToJson() const {
  return llvm::json::Object{
      {"name", name_},
  };
}

llvm::json::Value LifetimeName::ToJson() const {
  return llvm::json::Object{
      {"name", name},
      {"id", id},
  };
}

llvm::json::Value CcType::ToJson() const {
  llvm::json::Object variant_object = std::visit(
      visitor{
          [&](CcType::Primitive primitive) {
            return llvm::json::Object{{"Primitive", primitive.spelling}};
          },
          [&](CcType::PointerType pointer) {
            return llvm::json::Object{
                {"Pointer",
                 llvm::json::Object{
                     {
                         "kind",
                         [&]() -> llvm::json::Value {
                           switch (pointer.kind) {
                             case PointerTypeKind::kLValueRef:
                               return "LValueRef";
                             case PointerTypeKind::kRValueRef:
                               return "RValueRef";
                             case PointerTypeKind::kNullable:
                               return "Nullable";
                             case PointerTypeKind::kNonNull:
                               return "NonNull";
                           }
                         }(),
                     },
                     {"lifetime", pointer.lifetime},
                     {"pointee_type", *pointer.pointee_type},
                 }},
            };
          },
          [&](const CcType::FuncPointer& func_value) {
            std::vector<llvm::json::Value> param_and_return_type_values;
            param_and_return_type_values.reserve(
                func_value.param_and_return_types.size());
            for (const CcType& type : func_value.param_and_return_types) {
              param_and_return_type_values.push_back(type.ToJson());
            }
            return llvm::json::Object{
                {"FuncPointer",
                 llvm::json::Object{
                     {"non_null", func_value.non_null},
                     {
                         "call_conv",
                         [&]() -> llvm::json::Value {
                           switch (func_value.call_conv) {
                             case CallingConv::kC:
                               return "cdecl";
                             case CallingConv::kX86FastCall:
                               return "fastcall";
                             case CallingConv::kX86VectorCall:
                               return "vectorcall";
                             case CallingConv::kX864ThisCall:
                               return "thiscall";
                             case CallingConv::kX86StdCall:
                               return "stdcall";
                             case CallingConv::kWin64:
                               return "ms_abi";
                           }
                         }(),
                     },
                     {"param_and_return_types", param_and_return_type_values},
                 }},
            };
          },
          [&](ItemId id) { return llvm::json::Object{{"Decl", id}}; }},
      variant);

  return llvm::json::Object{
      {"variant", std::move(variant_object)},
      {"is_const", is_const},
      {"unknown_attr", unknown_attr},
  };
}

namespace {
CcType PointerOrReferenceTo(CcType pointee_type, PointerTypeKind pointer_kind,
                            std::optional<LifetimeId> lifetime) {
  return CcType(CcType::PointerType{
      .kind = pointer_kind,
      .lifetime = lifetime,
      .pointee_type = std::make_shared<CcType>(std::move(pointee_type)),
  });
}
}  // namespace

CcType CcType::PointerTo(CcType pointee_type,
                         std::optional<LifetimeId> lifetime, bool nullable) {
  return PointerOrReferenceTo(
      std::move(pointee_type),
      nullable ? PointerTypeKind::kNullable : PointerTypeKind::kNonNull,
      lifetime);
}

CcType CcType::LValueReferenceTo(CcType pointee_type,
                                 std::optional<LifetimeId> lifetime) {
  return PointerOrReferenceTo(std::move(pointee_type),
                              PointerTypeKind::kLValueRef, lifetime);
}

CcType CcType::RValueReferenceTo(CcType pointee_type,
                                 std::optional<LifetimeId> lifetime) {
  return PointerOrReferenceTo(std::move(pointee_type),
                              PointerTypeKind::kRValueRef, lifetime);
}

llvm::json::Value Identifier::ToJson() const {
  return llvm::json::Object{
      {"identifier", identifier_},
  };
}

llvm::json::Value IntegerConstant::ToJson() const {
  return llvm::json::Object{
      {"is_negative", is_negative_},
      {"wrapped_value", wrapped_value_},
  };
}

llvm::json::Value Operator::ToJson() const {
  return llvm::json::Object{
      {"name", name_},
  };
}

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

llvm::json::Value toJSON(const UnqualifiedIdentifier& unqualified_identifier) {
  if (auto* id = std::get_if<Identifier>(&unqualified_identifier)) {
    return llvm::json::Object{
        {"Identifier", *id},
    };
  } else if (auto* op = std::get_if<Operator>(&unqualified_identifier)) {
    return llvm::json::Object{
        {"Operator", *op},
    };
  } else {
    SpecialName special_name = std::get<SpecialName>(unqualified_identifier);
    return llvm::json::Object{
        {SpecialNameToString(special_name), nullptr},
    };
  }
}

llvm::json::Value FuncParam::ToJson() const {
  return llvm::json::Object{
      {"type", type},
      {"identifier", identifier},
      {"unknown_attr", unknown_attr},
  };
}

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

UnqualifiedIdentifier& TranslatedUnqualifiedIdentifier::rs_identifier() {
  if (crubit_rust_name.has_value()) {
    return *crubit_rust_name;
  }
  return cc_identifier;
}

Identifier& TranslatedIdentifier::rs_identifier() {
  if (crubit_rust_name.has_value()) {
    return *crubit_rust_name;
  }
  return cc_identifier;
}

llvm::json::Value MemberFuncMetadata::InstanceMethodMetadata::ToJson() const {
  const char* reference_str = nullptr;
  switch (reference) {
    case MemberFuncMetadata::kLValue:
      reference_str = "LValue";
      break;
    case MemberFuncMetadata::kRValue:
      reference_str = "RValue";
      break;
    case MemberFuncMetadata::kUnqualified:
      reference_str = "Unqualified";
      break;
  }

  return llvm::json::Object{
      {"reference", reference_str},
      {"is_const", is_const},
      {"is_virtual", is_virtual},
  };
}

llvm::json::Value MemberFuncMetadata::ToJson() const {
  return llvm::json::Object{
      {"record_id", record_id},
      {"instance_method_metadata", instance_method_metadata},
  };
}

llvm::json::Value ExistingRustType::ToJson() const {
  llvm::json::Object override{
      {"rs_name", rs_name},
      {"cc_name", cc_name},
      {"type_parameters", type_parameters},
      {"owning_target", owning_target},
      {"is_same_abi", is_same_abi},
      {"id", id},
      {"must_bind", must_bind},
  };
  if (size_align.has_value()) {
    override.insert({"size_align", size_align->ToJson()});
  }

  return llvm::json::Object{
      {"ExistingRustType", std::move(override)},
  };
}

llvm::json::Value UseMod::ToJson() const {
  llvm::json::Object use_mod{
      {"path", path},
      {"mod_name", mod_name},
      {"id", id},
      {"must_bind", must_bind},
  };

  return llvm::json::Object{
      {"UseMod", std::move(use_mod)},
  };
}

static std::string SafetyAnnotationToString(
    SafetyAnnotation safety_annotation) {
  switch (safety_annotation) {
    case SafetyAnnotation::kDisableUnsafe:
      return "DisableUnsafe";
    case SafetyAnnotation::kUnsafe:
      return "Unsafe";
    case SafetyAnnotation::kUnannotated:
      return "Unannotated";
  }
}

llvm::json::Value Func::ToJson() const {
  llvm::json::Object func{
      {"cc_name", cc_name},
      {"rs_name", rs_name},
      {"owning_target", owning_target},
      {"doc_comment", doc_comment},
      {"mangled_name", mangled_name},
      {"return_type", return_type},
      {"params", params},
      {"lifetime_params", lifetime_params},
      {"is_inline", is_inline},
      {"member_func_metadata", member_func_metadata},
      {"is_extern_c", is_extern_c},
      {"is_noreturn", is_noreturn},
      {"is_variadic", is_variadic},
      {"is_consteval", is_consteval},
      {"nodiscard", nodiscard},
      {"deprecated", deprecated},
      {"has_c_calling_convention", has_c_calling_convention},
      {"is_member_or_descendant_of_class_template",
       is_member_or_descendant_of_class_template},
      {"safety_annotation", SafetyAnnotationToString(safety_annotation)},
      {"source_loc", source_loc},
      {"id", id},
      {"enclosing_item_id", enclosing_item_id},
      {"adl_enclosing_record", adl_enclosing_record},
      {"must_bind", must_bind},
  };

  return llvm::json::Object{
      {"Func", std::move(func)},
  };
}

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

llvm::json::Value Field::ToJson() const {
  return llvm::json::Object{
      {"rust_identifier", rust_identifier},
      {"cpp_identifier", cpp_identifier},
      {"doc_comment", doc_comment},
      {"type", type},
      {"access", AccessToString(access)},
      {"offset", offset},
      {"size", size},
      {"unknown_attr", toJSON(unknown_attr)},
      {"is_no_unique_address", is_no_unique_address},
      {"is_bitfield", is_bitfield},
      {"is_inheritable", is_inheritable},
  };
}

llvm::json::Value toJSON(const SpecialMemberFunc& f) {
  switch (f) {
    case SpecialMemberFunc::kTrivial:
      return "Trivial";
    case SpecialMemberFunc::kNontrivialMembers:
      return "NontrivialMembers";
    case SpecialMemberFunc::kNontrivialUserDefined:
      return "NontrivialUserDefined";
    case SpecialMemberFunc::kUnavailable:
      return "Unavailable";
  }
}

llvm::json::Value BaseClass::ToJson() const {
  return llvm::json::Object{
      {"base_record_id", base_record_id},
      {"offset", offset},
  };
}

static std::string RecordTypeToString(RecordType record_type) {
  switch (record_type) {
    case kStruct:
      return "Struct";
    case kUnion:
      return "Union";
    case kClass:
      return "Class";
  }
}

std::ostream& operator<<(std::ostream& o, const RecordType& record_type) {
  return o << RecordTypeToString(record_type);
}

llvm::json::Value IncompleteRecord::ToJson() const {
  llvm::json::Object record{{"cc_name", cc_name},
                            {"rs_name", rs_name},
                            {"id", id},
                            {"owning_target", owning_target},
                            {"unknown_attr", unknown_attr},
                            {"record_type", RecordTypeToString(record_type)},
                            {"enclosing_item_id", enclosing_item_id},
                            {"must_bind", must_bind}};

  return llvm::json::Object{
      {"IncompleteRecord", std::move(record)},
  };
}

llvm::json::Value SizeAlign::ToJson() const {
  return llvm::json::Object{
      {"size", size},
      {"alignment", alignment},
  };
}

llvm::json::Value BridgeType::ToJson() const {
  return std::visit(
      visitor{
          [&](const BridgeType::BridgeVoidConverters& annotation) {
            return llvm::json::Object{{
                "BridgeVoidConverters",
                llvm::json::Object{
                    {"rust_name", annotation.rust_name},
                    {"rust_to_cpp_converter", annotation.rust_to_cpp_converter},
                    {"cpp_to_rust_converter", annotation.cpp_to_rust_converter},
                },
            }};
          },
          [&](const BridgeType::Bridge& annotation) {
            return llvm::json::Object{{
                "Bridge",
                llvm::json::Object{
                    {"rust_name", annotation.rust_name},
                    {"abi_rust", annotation.abi_rust},
                    {"abi_cpp", annotation.abi_cpp},
                },
            }};
          },
          [&](const BridgeType::StdOptional& std_optional) {
            return llvm::json::Object{
                {"StdOptional", std_optional.inner_type->ToJson()}};
          },
          [&](const BridgeType::StdPair& std_pair) {
            return llvm::json::Object{
                {"StdPair", llvm::json::Array{
                                std_pair.first_type->ToJson(),
                                std_pair.second_type->ToJson(),
                            }}};
          },
          [&](const BridgeType::StdString& std_string) {
            return llvm::json::Object{{"StdString", nullptr}};
          },
          [&](const BridgeType::ProtoMessageBridge& proto_message_bridge) {
            return llvm::json::Object{{
                "ProtoMessageBridge",
                llvm::json::Object{
                    {"rust_name", proto_message_bridge.rust_name},
                    {"abi_rust", proto_message_bridge.abi_rust},
                    {"abi_cpp", proto_message_bridge.abi_cpp},
                },
            }};
          },
      },
      variant);
}

llvm::json::Value TemplateArg::ToJson() const {
  return llvm::json::Object{
      {"type", type},
  };
}

llvm::json::Value TemplateSpecialization::ToJson() const {
  return llvm::json::Object{
      {"is_string_view", is_string_view},
      {"is_wstring_view", is_wstring_view},
      {"defining_target", defining_target},
      {"template_name", template_name},
      {"template_args", template_args},
  };
}

TraitImplPolarity* absl_nullable TraitDerives::Polarity(
    absl::string_view trait) {
  // <internal link> start
  if (trait == "Clone") return &clone;
  if (trait == "Copy") return &copy;
  if (trait == "Debug") return &debug;
  // <internal link> end
  return nullptr;
}

static std::string TraitImplPolarityToString(TraitImplPolarity polarity) {
  switch (polarity) {
    case TraitImplPolarity::kNegative:
      return "Negative";
    case TraitImplPolarity::kNone:
      return "None";
    case TraitImplPolarity::kPositive:
      return "Positive";
  }
}

llvm::json::Value TraitDerives::ToJson() const {
  return llvm::json::Object{
      // <internal link> start
      {"clone", TraitImplPolarityToString(clone)},
      {"copy", TraitImplPolarityToString(copy)},
      {"debug", TraitImplPolarityToString(debug)},
      // <internal link> end
      {"send", send},
      {"sync", sync},
      {"custom", custom},
  };
}

llvm::json::Value Record::ToJson() const {
  std::vector<llvm::json::Value> json_item_ids;
  json_item_ids.reserve(child_item_ids.size());
  for (const auto& id : child_item_ids) {
    json_item_ids.push_back(id.value());
  }

  llvm::json::Object record{
      {"rs_name", rs_name},
      {"cc_name", cc_name},
      {"mangled_cc_name", mangled_cc_name},
      {"id", id},
      {"owning_target", owning_target},
      {"template_specialization", template_specialization},
      {"unknown_attr", unknown_attr},
      {"doc_comment", doc_comment},
      {"bridge_type", bridge_type},
      {"source_loc", source_loc},
      {"unambiguous_public_bases", unambiguous_public_bases},
      {"fields", fields},
      {"lifetime_params", lifetime_params},
      {"size_align", size_align.ToJson()},
      {"trait_derives", trait_derives.ToJson()},
      {"is_derived_class", is_derived_class},
      {"override_alignment", override_alignment},
      {"is_unsafe_type", is_unsafe_type},
      {"copy_constructor", copy_constructor},
      {"move_constructor", move_constructor},
      {"destructor", destructor},
      {"is_trivial_abi", is_trivial_abi},
      {"is_inheritable", is_inheritable},
      {"is_abstract", is_abstract},
      {"nodiscard", nodiscard},
      {"record_type", RecordTypeToString(record_type)},
      {"is_aggregate", is_aggregate},
      {"is_anon_record_with_typedef", is_anon_record_with_typedef},
      {"child_item_ids", std::move(json_item_ids)},
      {"enclosing_item_id", enclosing_item_id},
      {"must_bind", must_bind},
  };

  return llvm::json::Object{
      {"Record", std::move(record)},
  };
}

llvm::json::Value Enumerator::ToJson() const {
  return llvm::json::Object{
      {"identifier", identifier},
      {"value", value},
      {"unknown_attr", unknown_attr},
  };
}

llvm::json::Value Enum::ToJson() const {
  llvm::json::Object enum_ir{
      {"cc_name", cc_name},
      {"rs_name", rs_name},
      {"id", id},
      {"owning_target", owning_target},
      {"source_loc", source_loc},
      {"underlying_type", underlying_type},
      {"enumerators", enumerators},
      {"unknown_attr", unknown_attr},
      {"enclosing_item_id", enclosing_item_id},
      {"must_bind", must_bind},
  };

  return llvm::json::Object{
      {"Enum", std::move(enum_ir)},
  };
}

llvm::json::Value GlobalVar::ToJson() const {
  llvm::json::Object var{
      {"cc_name", cc_name},
      {"rs_name", rs_name},
      {"id", id},
      {"owning_target", owning_target},
      {"source_loc", source_loc},
      {"mangled_name", mangled_name},
      {"type", type},
      {"unknown_attr", unknown_attr},
      {"enclosing_item_id", enclosing_item_id},
      {"must_bind", must_bind},
  };

  return llvm::json::Object{
      {"GlobalVar", std::move(var)},
  };
}

llvm::json::Value TypeAlias::ToJson() const {
  llvm::json::Object type_alias{{"cc_name", cc_name},
                                {"rs_name", rs_name},
                                {"id", id},
                                {"owning_target", owning_target},
                                {"unknown_attr", unknown_attr},
                                {"doc_comment", doc_comment},
                                {"underlying_type", underlying_type},
                                {"source_loc", source_loc},
                                {"enclosing_item_id", enclosing_item_id},
                                {"must_bind", must_bind}};

  return llvm::json::Object{
      {"TypeAlias", std::move(type_alias)},
  };
}

FormattedError FormattedError::FromStatus(absl::Status status) {
  std::optional<absl::Cord> fmt_cord =
      status.GetPayload(FormattedError::kFmtPayloadTypeUrl);
  std::string fmt;
  if (fmt_cord) {
    fmt = std::string(*fmt_cord);
  } else {
    fmt = absl::StrCat("(unannotated `",
                       absl::StatusCodeToString(status.code()), "` status)");
  }
  return FormattedError(fmt, std::string(status.message()));
}

llvm::json::Value FormattedError::ToJson() const {
  return llvm::json::Object{
      {"fmt", fmt_},
      {"message", message_},
  };
}

static std::string UnsupportedItemKindToString(UnsupportedItem::Kind kind) {
  switch (kind) {
    case UnsupportedItem::Kind::kFunc:
      return "Func";
    case UnsupportedItem::Kind::kGlobalVar:
      return "GlobalVar";
    case UnsupportedItem::Kind::kStruct:
      return "Struct";
    case UnsupportedItem::Kind::kUnion:
      return "Union";
    case UnsupportedItem::Kind::kClass:
      return "Class";
    case UnsupportedItem::Kind::kEnum:
      return "Enum";
    case UnsupportedItem::Kind::kTypeAlias:
      return "TypeAlias";
    case UnsupportedItem::Kind::kNamespace:
      return "Namespace";
    case UnsupportedItem::Kind::kConstructor:
      return "Constructor";
    case UnsupportedItem::Kind::kOther:
      return "Other";
  }
}

llvm::json::Value UnsupportedItem::Path::ToJson() const {
  return llvm::json::Object{
      {"ident", ident},
      {"enclosing_item_id", enclosing_item_id},
  };
}

llvm::json::Value UnsupportedItem::ToJson() const {
  std::vector<llvm::json::Value> json_errors;
  json_errors.reserve(errors.size());
  for (const auto& error : errors) {
    json_errors.push_back(error.ToJson());
  }

  llvm::json::Object unsupported{
      {"name", name},
      {"kind", UnsupportedItemKindToString(kind)},
      {"path", path},
      {"errors", json_errors},
      {"source_loc", source_loc},
      {"id", id},
      {"must_bind", must_bind},
  };

  return llvm::json::Object{
      {"UnsupportedItem", std::move(unsupported)},
  };
}

llvm::json::Value Comment::ToJson() const {
  llvm::json::Object comment{
      {"text", text},
      {"id", id},
      {"must_bind", must_bind},
  };
  comment["id"] = id.value();
  return llvm::json::Object{
      {"Comment", std::move(comment)},
  };
}

llvm::json::Value Namespace::ToJson() const {
  std::vector<llvm::json::Value> json_item_ids;
  json_item_ids.reserve(child_item_ids.size());
  for (const auto& id : child_item_ids) {
    json_item_ids.push_back(id.value());
  }

  llvm::json::Object ns{
      {"cc_name", cc_name},
      {"rs_name", rs_name},
      {"id", id},
      {"canonical_namespace_id", canonical_namespace_id},
      {"unknown_attr", unknown_attr},
      {"owning_target", owning_target},
      {"child_item_ids", std::move(json_item_ids)},
      {"enclosing_item_id", enclosing_item_id},
      {"is_inline", is_inline},
      {"must_bind", must_bind},
  };

  return llvm::json::Object{
      {"Namespace", std::move(ns)},
  };
}

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

  llvm::json::Object top_level_item_ids_json;
  for (const auto& [target, item_ids] : top_level_item_ids) {
    std::vector<llvm::json::Value> item_ids_json;
    item_ids_json.reserve(item_ids.size());
    for (const auto& item_id : item_ids) {
      item_ids_json.push_back(item_id.value());
    }
    top_level_item_ids_json[target.value()] = std::move(item_ids_json);
  }

  llvm::json::Object features_json;
  for (const auto& [target, features] : crubit_features) {
    std::vector<llvm::json::Value> feature_array;
    for (const std::string& feature : features) {
      feature_array.push_back(feature);
    }
    features_json[target.value()] = std::move(feature_array);
  }

  llvm::json::Object result{
      {"public_headers", public_headers},
      {"current_target", current_target},
      {"items", std::move(json_items)},
      {"top_level_item_ids", std::move(top_level_item_ids_json)},
      {"crubit_features", std::move(features_json)},
  };
  if (!crate_root_path.empty()) {
    result["crate_root_path"] = crate_root_path;
  }
  return std::move(result);
}

std::string ItemToString(const IR::Item& item) {
  return std::visit(
      [&](auto&& item) { return llvm::formatv("{0}", item.ToJson()); }, item);
}

void SetMustBindItem(IR::Item& item) {
  // All IR::Item variants have a `must_bind` field.
  std::visit([](auto& item_variant) { item_variant.must_bind = true; }, item);
}

}  // namespace crubit
