// 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/expr/cast.h"

#include <limits>

#include <gtest/gtest.h>

#include "src/developer/debug/zxdb/common/err.h"
#include "src/developer/debug/zxdb/common/test_with_loop.h"
#include "src/developer/debug/zxdb/expr/eval_test_support.h"
#include "src/developer/debug/zxdb/expr/expr_value.h"
#include "src/developer/debug/zxdb/expr/mock_eval_context.h"
#include "src/developer/debug/zxdb/expr/virtual_inheritance_test_setup.h"
#include "src/developer/debug/zxdb/symbols/base_type.h"
#include "src/developer/debug/zxdb/symbols/collection.h"
#include "src/developer/debug/zxdb/symbols/enumeration.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/type_test_support.h"

namespace zxdb {

namespace {

class Cast : public TestWithLoop {
 public:
  ErrOrValue SyncCastExprValue(const fxl::RefPtr<EvalContext>& eval_context, CastType cast_type,
                               const ExprValue& source, const fxl::RefPtr<Type>& dest_type,
                               const ExprValueSource& dest_source = ExprValueSource()) {
    ErrOrValue result(Err("Uncalled"));
    bool called = false;
    CastExprValue(eval_context, cast_type, source, dest_type, dest_source,
                  [&result, &called](ErrOrValue v) {
                    result = std::move(v);
                    called = true;
                  });

    loop().RunUntilNoTasks();
    EXPECT_TRUE(called);
    return result;
  }

  // When a cast is supported by CastNumericExprValue, an implicit cast should give the same
  // result. This runs both, expecting success, and that the answers match.
  //
  // To test a case where CastNumericExprValue() fails, call it directly since the more general case
  // might return a different answer.
  ExprValue SyncCastNumericExprValue(const fxl::RefPtr<EvalContext>& eval_context,
                                     const ExprValue& source, const fxl::RefPtr<Type>& dest_type,
                                     const ExprValueSource& dest_source = ExprValueSource()) {
    ErrOrValue full_result =
        SyncCastExprValue(eval_context, CastType::kImplicit, source, dest_type, dest_source);
    EXPECT_TRUE(full_result.ok());
    if (full_result.has_error())
      return ExprValue();

    ErrOrValue numeric_result = CastNumericExprValue(eval_context, source, dest_type, dest_source);
    EXPECT_TRUE(numeric_result.ok());
    if (numeric_result.has_error())
      return ExprValue();

    EXPECT_EQ(numeric_result.value(), full_result.value());
    return numeric_result.value();
  }
};

}  // namespace

// Tests both the implicit numeric and implicit regular cast functions.
TEST_F(Cast, Implicit) {
  auto eval_context = fxl::MakeRefCounted<MockEvalContext>();

  auto int32_type = MakeInt32Type();
  auto uint32_type = MakeInt32Type();
  auto int64_type = MakeInt64Type();
  auto uint64_type = MakeInt64Type();
  auto char_type = fxl::MakeRefCounted<BaseType>(BaseType::kBaseTypeSignedChar, 1, "char");
  auto bool_type = fxl::MakeRefCounted<BaseType>(BaseType::kBaseTypeBoolean, 1, "bool");
  auto float_type = fxl::MakeRefCounted<BaseType>(BaseType::kBaseTypeFloat, 4, "float");
  auto double_type = fxl::MakeRefCounted<BaseType>(BaseType::kBaseTypeFloat, 8, "double");

  ExprValue int32_one(int32_type, {1, 0, 0, 0});
  ExprValue int32_minus_one(int32_type, {0xff, 0xff, 0xff, 0xff});

  // Simple identity conversion.
  ExprValue out = SyncCastNumericExprValue(eval_context, int32_one, int32_type);
  EXPECT_EQ(int32_one, out);

  // Signed/unsigned conversion, should just copy the bits (end up with 0xffffffff),
  out = SyncCastNumericExprValue(eval_context, int32_minus_one, uint32_type);
  EXPECT_EQ(uint32_type.get(), out.type());
  EXPECT_EQ(int32_minus_one.data(), out.data());

  // Signed integer promotion.
  out = SyncCastNumericExprValue(eval_context, int32_minus_one, uint64_type);
  EXPECT_EQ(uint64_type.get(), out.type());
  EXPECT_EQ(std::numeric_limits<uint64_t>::max(), out.GetAs<uint64_t>());

  // Integer truncation
  out = SyncCastNumericExprValue(eval_context, int32_minus_one, char_type);
  EXPECT_EQ(char_type.get(), out.type());
  EXPECT_EQ(-1, out.GetAs<int8_t>());

  // Zero integer to boolean.
  ExprValue int32_zero(int32_type, {0, 0, 0, 0});
  out = SyncCastNumericExprValue(eval_context, int32_zero, bool_type);
  EXPECT_EQ(bool_type.get(), out.type());
  EXPECT_EQ(0, out.GetAs<int8_t>());

  // Nonzero integer to boolean.
  out = SyncCastNumericExprValue(eval_context, int32_minus_one, bool_type);
  EXPECT_EQ(bool_type.get(), out.type());
  EXPECT_EQ(1, out.GetAs<int8_t>());

  // Zero floating point to boolean.
  ExprValue float_minus_zero(float_type, {0, 0, 0, 0x80});
  out = SyncCastNumericExprValue(eval_context, float_minus_zero, bool_type);
  EXPECT_EQ(0, out.GetAs<int8_t>());

  // Nonzero floating point to boolean.
  ExprValue float_one_third(float_type, {0xab, 0xaa, 0xaa, 0x3e});
  out = SyncCastNumericExprValue(eval_context, float_one_third, bool_type);
  EXPECT_EQ(1, out.GetAs<int8_t>());

  // Float to signed.
  ExprValue float_minus_two(float_type, {0x00, 0x00, 0x00, 0xc0});
  out = SyncCastNumericExprValue(eval_context, float_minus_two, int32_type);
  EXPECT_EQ(-2, out.GetAs<int32_t>());

  // Float to unsigned.
  out = SyncCastNumericExprValue(eval_context, float_minus_two, uint64_type);
  EXPECT_EQ(static_cast<uint64_t>(-2), out.GetAs<uint64_t>());

  // Floating point promotion.
  out = SyncCastNumericExprValue(eval_context, float_minus_two, double_type);
  EXPECT_EQ(-2.0, out.GetAs<double>());
  ExprValue double_minus_two = out;

  // Floating point truncation.
  out = SyncCastNumericExprValue(eval_context, double_minus_two, float_type);
  EXPECT_EQ(-2.0f, out.GetAs<float>());

  // Pointer to integer with truncation.
  auto ptr_to_double_type = fxl::MakeRefCounted<ModifiedType>(DwarfTag::kPointerType, double_type);
  ExprValue ptr_value(ptr_to_double_type, {0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12});
  out = SyncCastNumericExprValue(eval_context, ptr_value, uint32_type);
  EXPECT_EQ(0x9abcdef0, out.GetAs<uint32_t>());
  ExprValue big_int_value = out;

  // Integer to pointer with expansion.
  out = SyncCastNumericExprValue(eval_context, int32_minus_one, ptr_to_double_type);
  EXPECT_EQ(-1, out.GetAs<int64_t>());

  // Test explicit boolean casts for the above values.
  EXPECT_TRUE(CastNumericExprValueToBool(eval_context, int32_one).value());
  EXPECT_TRUE(CastNumericExprValueToBool(eval_context, int32_minus_one).value());
  EXPECT_FALSE(CastNumericExprValueToBool(eval_context, int32_zero).value());
  EXPECT_FALSE(CastNumericExprValueToBool(eval_context, float_minus_zero).value());
  EXPECT_TRUE(CastNumericExprValueToBool(eval_context, float_one_third).value());
  EXPECT_TRUE(CastNumericExprValueToBool(eval_context, float_minus_two).value());
  EXPECT_TRUE(CastNumericExprValueToBool(eval_context, double_minus_two).value());
  EXPECT_TRUE(CastNumericExprValueToBool(eval_context, ptr_value).value());
}

// Enums can be casted to and fro.
TEST_F(Cast, Enum) {
  auto eval_context = fxl::MakeRefCounted<MockEvalContext>();

  // Enumeration values used in both enums below.
  Enumeration::Map values;
  values[0] = "kZero";
  values[1] = "kOne";
  values[static_cast<uint64_t>(-1)] = "kMinus";

  // An untyped enum (old-style C with no qualification). This one is unsigned.
  auto untyped = fxl::MakeRefCounted<Enumeration>("Untyped", LazySymbol(), 4, false, values);

  // An explicitly-typed 8-bit signed enum
  auto char_type = fxl::MakeRefCounted<BaseType>(BaseType::kBaseTypeSignedChar, 1, "char");
  auto typed = fxl::MakeRefCounted<Enumeration>("Untyped", char_type, 1, true, values);

  ExprValue untyped_value(untyped, {1, 0, 0, 0});
  ExprValue typed_value(typed, {1});

  // Untyped to int32.
  auto int32_type = MakeInt32Type();
  ErrOrValue out = SyncCastExprValue(eval_context, CastType::kImplicit, untyped_value, int32_type);
  EXPECT_FALSE(out.has_error()) << out.err().msg();
  EXPECT_EQ(1, out.value().GetAs<int32_t>());

  // Typed to int32.
  out = SyncCastExprValue(eval_context, CastType::kImplicit, typed_value, int32_type);
  EXPECT_FALSE(out.has_error()) << out.err().msg();
  EXPECT_EQ(1, out.value().GetAs<int32_t>());

  // Untyped to char.
  out = SyncCastExprValue(eval_context, CastType::kImplicit, untyped_value, char_type);
  EXPECT_FALSE(out.has_error()) << out.err().msg();
  EXPECT_EQ(1, out.value().GetAs<int8_t>());

  // Typed to char.
  out = SyncCastExprValue(eval_context, CastType::kImplicit, typed_value, char_type);
  EXPECT_FALSE(out.has_error()) << out.err().msg();
  EXPECT_EQ(1, out.value().GetAs<int8_t>());

  // Signed char to untyped (should be sign-extended).
  ExprValue char_minus_one(char_type, {0xff});
  out = SyncCastExprValue(eval_context, CastType::kImplicit, char_minus_one, untyped);
  EXPECT_FALSE(out.has_error()) << out.err().msg();
  EXPECT_EQ(-1, out.value().GetAs<int32_t>());

  // Signed char to typed.
  out = SyncCastExprValue(eval_context, CastType::kImplicit, char_minus_one, typed);
  EXPECT_FALSE(out.has_error()) << out.err().msg();
  EXPECT_EQ(-1, out.value().GetAs<int8_t>());
}

// Tests implicit casting when there are derived classes.
TEST_F(Cast, ImplicitDerived) {
  auto eval_context = fxl::MakeRefCounted<MockEvalContext>();

  DerivedClassTestSetup d;

  // Should be able to implicit cast Derived to Base1 object.
  ErrOrValue out =
      SyncCastExprValue(eval_context, CastType::kImplicit, d.derived_value, d.base1_type);
  EXPECT_FALSE(out.has_error());
  EXPECT_EQ(d.base1_type.get(), out.value().type());
  EXPECT_EQ(d.base1_value, out.value());
  // Check the source explicitly since == doesn't check sources.
  EXPECT_EQ(d.base1_value.source(), out.value().source());

  // Same for base 2.
  out = SyncCastExprValue(eval_context, CastType::kImplicit, d.derived_value, d.base2_type);
  EXPECT_FALSE(out.has_error());
  EXPECT_EQ(d.base2_type.get(), out.value().type());
  EXPECT_EQ(d.base2_value, out.value());
  // Check the source explicitly since == doesn't check sources.
  EXPECT_EQ(d.base2_value.source(), out.value().source());

  // Should not be able to implicit cast from Base2 to Derived.
  out.value() = ExprValue();
  out = SyncCastExprValue(eval_context, CastType::kImplicit, d.base2_value, d.derived_type);
  EXPECT_TRUE(out.has_error());

  // Pointer casting: should be able to implicit cast derived ptr to base ptr type. This data
  // matches kDerivedAddr in 64-bit little endian.
  out = SyncCastExprValue(eval_context, CastType::kImplicit, d.derived_ptr_value, d.base2_ptr_type);
  EXPECT_FALSE(out.has_error()) << out.err().msg();

  // That should have adjusted the pointer value appropriately.
  EXPECT_EQ(d.base2_ptr_value, out.value());

  // Should not allow implicit casts from Base to Derived.
  out = SyncCastExprValue(eval_context, CastType::kImplicit, d.base2_ptr_value, d.derived_ptr_type);
  EXPECT_TRUE(out.has_error());
  EXPECT_EQ("Can't convert 'Base2*' to unrelated type 'Derived*'.", out.err().msg());

  // Cast a derived to void* is allowed, just a numeric copy.
  auto void_ptr_type = fxl::MakeRefCounted<ModifiedType>(DwarfTag::kPointerType, LazySymbol());
  out = SyncCastExprValue(eval_context, CastType::kImplicit, d.derived_ptr_value, void_ptr_type);
  EXPECT_FALSE(out.has_error()) << out.err().msg();
  ExprValue void_ptr_value(void_ptr_type, d.derived_ptr_value.data());
  EXPECT_EQ(void_ptr_value, out.value());

  // Cast void* to any pointer type (in C this would require an explicit cast).
  out = SyncCastExprValue(eval_context, CastType::kImplicit, void_ptr_value, d.derived_ptr_type);
  EXPECT_FALSE(out.has_error()) << out.err().msg();
  EXPECT_EQ(d.derived_ptr_value, out.value());
}

TEST_F(Cast, Reinterpret) {
  auto eval_context = fxl::MakeRefCounted<MockEvalContext>();

  auto int32_type = MakeInt32Type();
  auto uint32_type = MakeInt32Type();
  auto int64_type = MakeInt64Type();
  auto uint64_type = MakeInt64Type();
  auto char_type = fxl::MakeRefCounted<BaseType>(BaseType::kBaseTypeSignedChar, 1, "char");
  auto bool_type = fxl::MakeRefCounted<BaseType>(BaseType::kBaseTypeBoolean, 1, "bool");
  auto double_type = fxl::MakeRefCounted<BaseType>(BaseType::kBaseTypeFloat, 8, "double");

  auto ptr_to_int32_type = fxl::MakeRefCounted<ModifiedType>(DwarfTag::kPointerType, int32_type);
  auto ptr_to_void_type = fxl::MakeRefCounted<ModifiedType>(DwarfTag::kPointerType, LazySymbol());

  ExprValue int32_minus_one(int32_type, {0xff, 0xff, 0xff, 0xff});
  ExprValue int64_big_num(int32_type, {8, 7, 6, 5, 4, 3, 2, 1});
  ExprValue ptr_to_void(ptr_to_void_type, {8, 7, 6, 5, 4, 3, 2, 1});
  ExprValue double_pi(double_type, {0x18, 0x2d, 0x44, 0x54, 0xfb, 0x21, 0x09, 0x40});

  // Two pointer types: reinterpret_cast<int32_t*>(ptr_to_void);
  ErrOrValue out =
      SyncCastExprValue(eval_context, CastType::kReinterpret, ptr_to_void, ptr_to_int32_type);
  EXPECT_FALSE(out.has_error());
  EXPECT_EQ(0x0102030405060708u, out.value().GetAs<uint64_t>());
  EXPECT_EQ(ptr_to_int32_type.get(), out.value().type());

  // Conversion from int to void*. C++ would prohibit this case because the integer is 32 bits and
  // the pointer is 64, but the debugger allows it.  This should not be sign extended.
  out = SyncCastExprValue(eval_context, CastType::kReinterpret, int32_minus_one, ptr_to_void_type);
  EXPECT_FALSE(out.has_error());
  EXPECT_EQ(0xffffffffu, out.value().GetAs<uint64_t>());

  // Truncation of a number. This is also disallowed in C++.
  out = SyncCastExprValue(eval_context, CastType::kReinterpret, int64_big_num, int32_type);
  EXPECT_FALSE(out.has_error());
  EXPECT_EQ(4u, out.value().data().size());
  EXPECT_EQ(0x05060708u, out.value().GetAs<uint32_t>());

  // Prohibit conversions between a double and a pointer: reinterpret_cast<void*>(3.14159265258979);
  out = SyncCastExprValue(eval_context, CastType::kReinterpret, double_pi, ptr_to_void_type);
  EXPECT_TRUE(out.has_error());
  EXPECT_EQ("Can't cast from a 'double'.", out.err().msg());
}

// Static cast is mostly implement as implicit cast. This only tests the additional behavior.
TEST_F(Cast, Static) {
  auto eval_context = fxl::MakeRefCounted<MockEvalContext>();

  DerivedClassTestSetup d;

  // Should NOT be able to static cast from Base2 to Derived.  This is "static_cast<Derived>(base);"
  ErrOrValue out =
      SyncCastExprValue(eval_context, CastType::kStatic, d.base2_value, d.derived_type);
  EXPECT_TRUE(out.has_error());

  // Cast a derived class reference to a base class reference.  This is
  // "static_cast<Base&>(derived_reference);
  out = SyncCastExprValue(eval_context, CastType::kStatic, d.derived_ref_value, d.base2_ref_type);
  EXPECT_FALSE(out.has_error()) << out.err().msg();
  EXPECT_EQ(d.base2_ref_value, out.value());

  // Should be able to go from base->derived with pointers.  This is "static_cast<Derived*>(&base);"
  out = SyncCastExprValue(eval_context, CastType::kStatic, d.base2_ptr_value, d.derived_ptr_type);
  EXPECT_FALSE(out.has_error()) << out.err().msg();
  EXPECT_EQ(d.derived_ptr_value, out.value());

  // Base->derived conversion for references.
  out = SyncCastExprValue(eval_context, CastType::kStatic, d.base2_ref_value, d.derived_ref_type);
  EXPECT_FALSE(out.has_error()) << out.err().msg();
  EXPECT_EQ(d.derived_ref_value, out.value());

  // Allow conversion of rvalue references and regular references.
  auto derived_rvalue_type =
      fxl::MakeRefCounted<ModifiedType>(DwarfTag::kRvalueReferenceType, d.derived_type);
  ExprValue derived_rvalue_value(derived_rvalue_type, d.derived_ref_value.data());
  out = SyncCastExprValue(eval_context, CastType::kStatic, derived_rvalue_value, d.base2_ref_type);
  EXPECT_FALSE(out.has_error());
  EXPECT_EQ(d.base2_ref_value, out.value());

  // Don't allow reference->pointer or pointer->reference casts.
  out = SyncCastExprValue(eval_context, CastType::kStatic, d.derived_ref_value, d.derived_ptr_type);
  EXPECT_TRUE(out.has_error());
  out = SyncCastExprValue(eval_context, CastType::kStatic, d.derived_ptr_value, d.derived_ref_type);
  EXPECT_TRUE(out.has_error());
}

TEST_F(Cast, C) {
  auto eval_context = fxl::MakeRefCounted<MockEvalContext>();

  DerivedClassTestSetup d;

  // A C-style cast should be like a static cast when casting between related types.
  ErrOrValue out =
      SyncCastExprValue(eval_context, CastType::kC, d.derived_ref_value, d.base2_ref_type);
  EXPECT_FALSE(out.has_error()) << out.err().msg();
  EXPECT_EQ(d.base2_ref_value, out.value());

  // When there are unrelated pointers, it should fall back to reinterpret.
  auto double_type = fxl::MakeRefCounted<BaseType>(BaseType::kBaseTypeFloat, 8, "double");
  auto ptr_to_double_type = fxl::MakeRefCounted<ModifiedType>(DwarfTag::kPointerType, double_type);
  ExprValue ptr_value(ptr_to_double_type, {0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12});
  out = SyncCastExprValue(eval_context, CastType::kC, ptr_value, d.base2_ptr_type);
  EXPECT_FALSE(out.has_error());

  // For the reinterpret cast, the type should be the new one, with the data being the original.
  EXPECT_EQ(d.base2_ptr_type.get(), out.value().type());
  EXPECT_EQ(ptr_value.data(), out.value().data());

  // Can't cast from a ptr to a ref.
  out = SyncCastExprValue(eval_context, CastType::kC, ptr_value, d.base2_ref_type);
  EXPECT_TRUE(out.has_error());
}

// Casting a pointer when there is virtual inheritance means evaluating a DWARF expression and
// fetching a bunch of memory to adjust the pointers.
//
// Note that virtual inheritance isn't inheritance with virtual methods, but rather:
//
//   class Derived : public virtual Base {};
//
// And this means that Base is accessed indirectly from a pointer in Derived, usually so that
// diamond inheritance can be resolved. See resolve_collection_unittest.cc for more virtual
// inheritance tests.
TEST_F(Cast, StaticCastVirtualInheritance) {
  auto eval_context = fxl::MakeRefCounted<MockEvalContext>();
  VirtualInheritanceTestSetup setup;
  setup.SaveMockData(eval_context->data_provider());

  // Casing from "derived" to "base" covers two regular and one virtual inheritance step. This is
  // the cast for literal objects.
  ErrOrValue result =
      SyncCastExprValue(eval_context, CastType::kStatic, setup.derived_value, setup.base);
  ASSERT_TRUE(result.ok()) << result.err().msg();
  EXPECT_EQ(setup.base.get(), result.value().type());
  EXPECT_EQ(setup.kBaseAddress, result.value().source().address());

  // The data of the base is the last 4 bytes of the full derived data.
  std::vector<uint8_t> expected_base_data(setup.derived_value.data().bytes().end() - 4,
                                          setup.derived_value.data().bytes().end());
  EXPECT_EQ(expected_base_data, result.value().data().bytes());

  // Now do a cast of pointers with the same thing.
  auto base_ptr_type = fxl::MakeRefCounted<ModifiedType>(DwarfTag::kPointerType, setup.base);
  auto derived_ptr_type = fxl::MakeRefCounted<ModifiedType>(DwarfTag::kPointerType, setup.derived);
  ExprValue derived_ptr(setup.kDerivedAddress, derived_ptr_type);
  result = SyncCastExprValue(eval_context, CastType::kStatic, derived_ptr, base_ptr_type);

  ASSERT_TRUE(result.ok()) << result.err().msg();
  EXPECT_EQ(base_ptr_type.get(), result.value().type());
  EXPECT_EQ(setup.kBaseAddress, result.value().GetAs<uint64_t>());
}

}  // namespace zxdb
