// Copyright 2018 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/debug/zxdb/symbols/type_test_support.h"

#include "src/developer/debug/zxdb/symbols/base_type.h"
#include "src/developer/debug/zxdb/symbols/collection.h"
#include "src/developer/debug/zxdb/symbols/compile_unit.h"
#include "src/developer/debug/zxdb/symbols/data_member.h"
#include "src/developer/debug/zxdb/symbols/inherited_from.h"
#include "src/developer/debug/zxdb/symbols/modified_type.h"
#include "src/developer/debug/zxdb/symbols/variant.h"
#include "src/developer/debug/zxdb/symbols/variant_part.h"
#include "src/lib/fxl/strings/string_printf.h"

namespace zxdb {

fxl::RefPtr<BaseType> MakeInt16Type() {
  return fxl::MakeRefCounted<BaseType>(BaseType::kBaseTypeSigned, 2, "int16_t");
}

fxl::RefPtr<BaseType> MakeInt32Type() {
  return fxl::MakeRefCounted<BaseType>(BaseType::kBaseTypeSigned, 4, "int32_t");
}

fxl::RefPtr<BaseType> MakeUint32Type() {
  return fxl::MakeRefCounted<BaseType>(BaseType::kBaseTypeUnsigned, 4, "uint32_t");
}

fxl::RefPtr<BaseType> MakeInt64Type() {
  return fxl::MakeRefCounted<BaseType>(BaseType::kBaseTypeSigned, 8, "int64_t");
}

fxl::RefPtr<BaseType> MakeUint64Type() {
  return fxl::MakeRefCounted<BaseType>(BaseType::kBaseTypeUnsigned, 8, "uint64_t");
}

fxl::RefPtr<BaseType> MakeFloatType() {
  return fxl::MakeRefCounted<BaseType>(BaseType::kBaseTypeFloat, 4, "float");
}

fxl::RefPtr<BaseType> MakeDoubleType() {
  return fxl::MakeRefCounted<BaseType>(BaseType::kBaseTypeFloat, 8, "double");
}

fxl::RefPtr<BaseType> MakeSignedChar8Type() {
  return fxl::MakeRefCounted<BaseType>(BaseType::kBaseTypeSignedChar, 1, "char");
}

fxl::RefPtr<BaseType> MakeUnsignedChar8Type() {
  return fxl::MakeRefCounted<BaseType>(BaseType::kBaseTypeUnsignedChar, 1, "unsigned char");
}

fxl::RefPtr<BaseType> MakeRustCharType() {
  auto type = fxl::MakeRefCounted<BaseType>(BaseType::kBaseTypeUnsignedChar, 4, "char");
  type->set_parent(UncachedLazySymbol::MakeUnsafe(MakeRustUnit()));
  return type;
}

fxl::RefPtr<ModifiedType> MakeRustCharPointerType() {
  auto char_type = MakeRustCharType();
  auto mod = fxl::MakeRefCounted<ModifiedType>(DwarfTag::kPointerType, char_type);
  mod->set_parent(UncachedLazySymbol::MakeUnsafe(char_type->parent().Get()));
  return mod;
}

fxl::RefPtr<ModifiedType> MakeCharPointerType() {
  return fxl::MakeRefCounted<ModifiedType>(DwarfTag::kPointerType, MakeSignedChar8Type());
}

fxl::RefPtr<Collection> MakeCollectionType(DwarfTag type_tag, const std::string& type_name,
                                           std::initializer_list<NameAndType> members) {
  return MakeCollectionTypeWithOffset(type_tag, type_name, 0, std::move(members));
}

fxl::RefPtr<Collection> MakeCollectionTypeWithOffset(DwarfTag type_tag,
                                                     const std::string& type_name,
                                                     uint32_t first_member_offset,
                                                     std::initializer_list<NameAndType> members) {
  auto result = fxl::MakeRefCounted<Collection>(type_tag, type_name);

  uint32_t offset = first_member_offset;

  uint32_t max_union_member_size = 0;  // For computing union sizes.

  std::vector<LazySymbol> data_members;
  for (const auto& [name, type] : members) {
    auto member = fxl::MakeRefCounted<DataMember>();
    member->set_assigned_name(name);
    member->set_type(type);
    member->set_member_location(offset);
    data_members.emplace_back(member);

    if (type_tag == DwarfTag::kUnionType)
      max_union_member_size = std::max(max_union_member_size, type->byte_size());
    else
      offset += type->byte_size();
  }

  if (type_tag == DwarfTag::kUnionType)
    result->set_byte_size(max_union_member_size);  // Unions are the max size of each member.
  else
    result->set_byte_size(offset);  // Adds up all member offsets.

  result->set_data_members(std::move(data_members));
  return result;
}

fxl::RefPtr<Collection> MakeDerivedClassPair(DwarfTag type_tag, const std::string& base_name,
                                             std::initializer_list<NameAndType> base_members,
                                             const std::string& derived_name,
                                             std::initializer_list<NameAndType> derived_members) {
  auto base = MakeCollectionTypeWithOffset(type_tag, base_name, 0, std::move(base_members));

  // Leave room at the beginning of |derived| for the base class.
  auto derived = MakeCollectionTypeWithOffset(type_tag, derived_name, base->byte_size(),
                                              std::move(derived_members));

  derived->set_inherited_from({LazySymbol(fxl::MakeRefCounted<InheritedFrom>(base, 0))});
  return derived;
}

fxl::RefPtr<CompileUnit> MakeRustUnit() {
  auto unit = fxl::MakeRefCounted<CompileUnit>(fxl::WeakPtr<ModuleSymbols>(), DwarfLang::kRust,
                                               "<<internal>>", std::nullopt);
  return unit;
}

fxl::RefPtr<Variant> MakeRustVariant(const std::string& name, std::optional<uint64_t> discriminant,
                                     const std::vector<fxl::RefPtr<DataMember>>& members) {
  // For Rust triggering to happen the compilation unit must be set. The easiest way to do this is
  // to set the compilation unit as the parent.  This doesn't produce a strictly valid structure
  // since the parents won't be "right" when traversing the symbol hierarchy upward, but that's not
  // been necessary so far.
  //
  // TODO(brettw) have a better way to set the language for symbols.
  auto unit = MakeRustUnit();

  // Pick the byte size to be the size after the last member.
  uint32_t byte_size = 0;
  if (members.size() > 0) {
    byte_size =
        members.back()->member_location() + members.back()->type().Get()->As<Type>()->byte_size();
  }

  // The single member of the variant has a type name of the variant name.  This type holds all the
  // members passed in.
  auto variant_member_type = fxl::MakeRefCounted<Collection>(DwarfTag::kStructureType, name);
  variant_member_type->set_parent(UncachedLazySymbol::MakeUnsafe(unit));
  variant_member_type->set_byte_size(byte_size);

  std::vector<LazySymbol> lazy_members;
  for (const auto& member : members) {
    member->set_parent(UncachedLazySymbol::MakeUnsafe(unit));
    lazy_members.emplace_back(member);
  }
  variant_member_type->set_data_members(std::move(lazy_members));

  // This data member in the variant contains the structure above. We assume it starts at offset 0
  // in the containing struct.
  auto variant_data = fxl::MakeRefCounted<DataMember>(name, variant_member_type, 0);
  variant_data->set_parent(UncachedLazySymbol::MakeUnsafe(unit));

  auto var =
      fxl::MakeRefCounted<Variant>(discriminant, std::vector<LazySymbol>{LazySymbol(variant_data)});
  var->set_parent(UncachedLazySymbol::MakeUnsafe(unit));
  return var;
}

fxl::RefPtr<Collection> MakeRustEnum(const std::string& name, fxl::RefPtr<DataMember> discriminant,
                                     const std::vector<fxl::RefPtr<Variant>>& variants) {
  auto unit = MakeRustUnit();
  uint32_t byte_size = 0;

  std::vector<LazySymbol> lazy_variants;
  for (const auto& var : variants) {
    // Pick the size based on the largest variant
    if (!var->data_members().empty()) {
      const DataMember* last_member = var->data_members().back().Get()->As<DataMember>();
      FX_DCHECK(last_member);  // ASsume test code has set up properly.
      uint32_t var_byte_size =
          last_member->member_location() + last_member->type().Get()->As<Type>()->byte_size();
      if (var_byte_size > byte_size)
        byte_size = var_byte_size;
    }

    lazy_variants.emplace_back(var);
  }

  auto variant_part = fxl::MakeRefCounted<VariantPart>(discriminant, std::move(lazy_variants));
  variant_part->set_parent(UncachedLazySymbol::MakeUnsafe(unit));

  auto collection = fxl::MakeRefCounted<Collection>(DwarfTag::kStructureType, name);
  collection->set_variant_part(variant_part);
  collection->set_byte_size(byte_size);
  collection->set_parent(UncachedLazySymbol::MakeUnsafe(unit));

  return collection;
}

fxl::RefPtr<Collection> MakeTestRustEnum() {
  // Say "None is the default variant so has no discriminant (anything other than these values will
  // match "none".
  const uint64_t kScalarDiscriminant = 0;
  const uint64_t kPointDiscriminant = 1;

  // Set as parent to indicate this is a Rust value.
  auto unit = MakeRustUnit();

  // This 4-byte value encodes the discriminant value which indicates which
  // variant is valid. It's at offset 0 in the struct,
  auto uint32_type = MakeInt32Type();
  uint32_type->set_parent(UncachedLazySymbol::MakeUnsafe(unit));

  auto discriminant = fxl::MakeRefCounted<DataMember>(std::string(), uint32_type, 0);

  // None variant.
  auto none_variant = MakeRustVariant("None", std::nullopt, {});

  // Scalar variant. The member is named with "__0" like Rust does. All the members must start after
  // the discriminant above (4 bytes).
  auto scalar_data = fxl::MakeRefCounted<DataMember>("__0", uint32_type, 4);
  auto scalar_variant = MakeRustVariant("Scalar", kScalarDiscriminant,
                                        std::vector<fxl::RefPtr<DataMember>>{scalar_data});

  // Point variant. The two members start after the discriminant (4 bytes).
  auto x_data = fxl::MakeRefCounted<DataMember>("x", uint32_type, 4);
  auto y_data = fxl::MakeRefCounted<DataMember>("y", uint32_type, 8);
  auto point_variant = MakeRustVariant("Point", kPointDiscriminant,
                                       std::vector<fxl::RefPtr<DataMember>>{x_data, y_data});

  // Structure that contains the variants. It has a variant_part and no data.
  auto rust_enum =
      MakeRustEnum("RustEnum", discriminant, {none_variant, scalar_variant, point_variant});
  rust_enum->set_parent(UncachedLazySymbol::MakeUnsafe(MakeRustUnit()));
  return rust_enum;
}

}  // namespace zxdb
