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

#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/expr_value.h"
#include "src/developer/debug/zxdb/expr/mock_eval_context.h"
#include "src/developer/debug/zxdb/expr/pretty_type.h"
#include "src/developer/debug/zxdb/symbols/array_type.h"
#include "src/developer/debug/zxdb/symbols/base_type.h"
#include "src/developer/debug/zxdb/symbols/modified_type.h"
#include "src/developer/debug/zxdb/symbols/type_test_support.h"

namespace zxdb {

namespace {

class ResolveArrayTest : public TestWithLoop {};

// A PrettyType implementation that provides arracy access. This array access returns the index * 2
// as the array value.
class TestPrettyArray : public PrettyType {
 public:
  TestPrettyArray() {}

  void Format(FormatNode* node, const FormatOptions& options,
              const fxl::RefPtr<EvalContext>& context, fit::deferred_callback cb) override {}
  EvalArrayFunction GetArrayAccess() const override {
    return [](const fxl::RefPtr<EvalContext>&, const ExprValue& object_value, int64_t index,
              EvalCallback cb) { cb(ExprValue(index * 2)); };
  }
};

}  // namespace

// Tests the static resolution case when the source is a vector register. The "source" of array
// elements in this case is tricky.
TEST_F(ResolveArrayTest, ResolveVectorRegister) {
  auto eval_context = fxl::MakeRefCounted<MockEvalContext>();

  // Array holds 4 uint32_t.
  constexpr uint32_t kTypeSize = 4;
  auto elt_type = fxl::MakeRefCounted<BaseType>(BaseType::kBaseTypeUnsigned, kTypeSize, "uint32_t");
  auto array_type = fxl::MakeRefCounted<ArrayType>(elt_type, 4);

  std::vector<uint8_t> array_bytes = {0, 0, 0, 0,   // array[0] = 0
                                      1, 0, 0, 0,   // array[1] = 1
                                      2, 0, 0, 0,   // array[2] = 2
                                      3, 0, 0, 0};  // array[3] = 3
  constexpr debug::RegisterID register_id = debug::RegisterID::kX64_xmm3;
  ExprValue value(array_type, array_bytes, ExprValueSource(register_id));

  // Ask for all 4 values.
  bool called = false;
  ErrOrValueVector result((std::vector<ExprValue>()));
  ResolveArray(eval_context, nullptr, value, 0, 4, [&called, &result](ErrOrValueVector cb_result) {
    called = true;
    result = std::move(cb_result);
    debug::MessageLoop::Current()->QuitNow();
  });
  loop().RunUntilNoTasks();
  ASSERT_TRUE(called);

  EXPECT_FALSE(result.has_error());
  ASSERT_EQ(4u, result.value().size());

  // Each element should be 32 bits wide and shifted 32 bits more than the previous.
  EXPECT_EQ(0u, result.value()[0].GetAs<uint32_t>());
  EXPECT_EQ(ExprValueSource(register_id, 32, 0), result.value()[0].source());

  EXPECT_EQ(1u, result.value()[1].GetAs<uint32_t>());
  EXPECT_EQ(ExprValueSource(register_id, 32, 32), result.value()[1].source());

  EXPECT_EQ(2u, result.value()[2].GetAs<uint32_t>());
  EXPECT_EQ(ExprValueSource(register_id, 32, 64), result.value()[2].source());

  EXPECT_EQ(3u, result.value()[3].GetAs<uint32_t>());
  EXPECT_EQ(ExprValueSource(register_id, 32, 96), result.value()[3].source());
}

// Resolves an array element with a pointer as the base.
TEST_F(ResolveArrayTest, ResolvePointer) {
  auto eval_context = fxl::MakeRefCounted<MockEvalContext>();

  // Request 3 elements from 1-4.
  constexpr uint64_t kBaseAddress = 0x100000;
  constexpr uint32_t kBeginIndex = 1;
  constexpr uint32_t kEndIndex = 4;

  // Array holds 3 uint16_t.
  constexpr uint32_t kTypeSize = 2;
  auto elt_type = fxl::MakeRefCounted<BaseType>(BaseType::kBaseTypeUnsigned, kTypeSize, "uint16_t");
  auto ptr_type = fxl::MakeRefCounted<ModifiedType>(DwarfTag::kPointerType, elt_type);

  // Create memory with two values 0x3344, 0x5566. Note that these are offset one value from the
  // beginning of the array so the requested address of the kBeginIndex'th element matches this
  // address.
  constexpr uint64_t kBeginAddress = kBaseAddress + kBeginIndex * kTypeSize;
  eval_context->data_provider()->AddMemory(kBeginAddress, {0x44, 0x33, 0x66, 0x55});

  // Data in the value is the pointer to the beginning of the array.
  ExprValue value(ptr_type, {0, 0, 0x10, 0, 0, 0, 0, 0});

  bool called = false;
  ErrOrValueVector result((std::vector<ExprValue>()));
  ResolveArray(eval_context, nullptr, value, kBeginIndex, kEndIndex,
               [&called, &result](ErrOrValueVector cb_result) {
                 called = true;
                 result = std::move(cb_result);
                 debug::MessageLoop::Current()->QuitNow();
               });

  // Should be called async.
  EXPECT_FALSE(called);
  loop().Run();
  EXPECT_TRUE(called);

  // Should have returned two values (the overlap of the array and the requested range).
  ASSERT_TRUE(result.ok());
  ASSERT_EQ(2u, result.value().size());

  EXPECT_EQ(elt_type.get(), result.value()[0].type());
  EXPECT_EQ(0x3344, result.value()[0].GetAs<uint16_t>());
  EXPECT_EQ(kBaseAddress + kTypeSize, result.value()[0].source().address());

  EXPECT_EQ(elt_type.get(), result.value()[1].type());
  EXPECT_EQ(0x5566, result.value()[1].GetAs<uint16_t>());
  EXPECT_EQ(kBaseAddress + kTypeSize * 2, result.value()[1].source().address());

  // Test the one-element variant.
  called = false;
  ErrOrValue single_result((ExprValue()));
  ResolveArrayItem(eval_context, value, kBeginIndex, [&called, &single_result](ErrOrValue result) {
    called = true;
    single_result = std::move(result);
    debug::MessageLoop::Current()->QuitNow();
  });

  // Should be called async.
  EXPECT_FALSE(called);
  loop().Run();
  EXPECT_TRUE(called);

  ASSERT_TRUE(single_result.ok());
  EXPECT_EQ(elt_type.get(), single_result.value().type());
  EXPECT_EQ(0x3344, single_result.value().GetAs<uint16_t>());
  EXPECT_EQ(kBaseAddress + kTypeSize, single_result.value().source().address());
}

TEST_F(ResolveArrayTest, Invalid) {
  auto eval_context = fxl::MakeRefCounted<MockEvalContext>();

  // Resolving an array on an empty ExprValue.
  bool called = false;
  ResolveArrayItem(eval_context, ExprValue(), 1, [&called](ErrOrValue result) {
    called = true;
    EXPECT_TRUE(result.has_error());
    EXPECT_EQ("Can't resolve an array access on type '<Unknown>'.", result.err().msg());
  });
  EXPECT_TRUE(called);

  // Resolving an array on an integer type.
  called = false;
  ResolveArrayItem(eval_context, ExprValue(56), 1, [&called](ErrOrValue result) {
    called = true;
    EXPECT_TRUE(result.has_error());
    EXPECT_EQ("Can't resolve an array access on type 'int32_t'.", result.err().msg());
  });
  EXPECT_TRUE(called);
}

// Tests a PrettyType's implementation of [].
TEST_F(ResolveArrayTest, PrettyArray) {
  auto eval_context = fxl::MakeRefCounted<MockEvalContext>();

  const char kMyTypeName[] = "MyType";

  // Set up pretty array mock for "MyType".
  IdentifierGlob mytype_glob;
  ASSERT_FALSE(mytype_glob.Init(kMyTypeName).has_error());
  eval_context->pretty_type_manager().Add(ExprLanguage::kC, mytype_glob,
                                          std::make_unique<TestPrettyArray>());

  auto my_type = MakeCollectionType(DwarfTag::kStructureType, kMyTypeName, {});
  ExprValue my_value(my_type, {});

  constexpr uint64_t kIndex = 55;

  // Test the one-element variant.
  bool called = false;
  ErrOrValue result((ExprValue()));
  ResolveArrayItem(eval_context, my_value, kIndex, [&called, &result](ErrOrValue value) {
    called = true;
    result = std::move(value);
    debug::MessageLoop::Current()->QuitNow();
  });

  // The PrettyType executes synchronously so it should complete synchronouly.
  EXPECT_TRUE(called);
  ASSERT_TRUE(result.ok());

  // Result should be twice the input.
  EXPECT_EQ(kIndex * 2, result.value().GetAs<uint64_t>());
}

TEST_F(ResolveArrayTest, CoercePointerToArrayOfSize) {
  auto eval_context = fxl::MakeRefCounted<MockEvalContext>();

  constexpr uint64_t kBaseAddress = 0x100000;

  // Array holds 3 uint16_t.
  constexpr uint32_t kTypeSize = 2;
  auto elt_type = fxl::MakeRefCounted<BaseType>(BaseType::kBaseTypeUnsigned, kTypeSize, "uint16_t");
  auto ptr_type = fxl::MakeRefCounted<ModifiedType>(DwarfTag::kPointerType, elt_type);

  // The full array in memory including 3 items. The values are 0x1122, 0x3344, 0x5566
  std::vector<uint8_t> array_bytes = {0x22, 0x11, 0x44, 0x33, 0x66, 0x55};
  eval_context->data_provider()->AddMemory(kBaseAddress, array_bytes);

  ExprValue ptr_value(kBaseAddress, ptr_type);

  // This callback is used for all examples below.
  bool called = false;
  ErrOrValue result((ExprValue()));
  auto callback = [&called, &result](ErrOrValue value) {
    called = true;
    result = std::move(value);
    debug::MessageLoop::Current()->QuitNow();
  };

  // Request an array of size 2. It should fetch the memory.
  CoerceArraySize(eval_context, ptr_value, 2, callback);
  loop().RunUntilNoTasks();
  ASSERT_TRUE(called);
  ASSERT_TRUE(result.ok());
  ASSERT_EQ(kTypeSize * 2, result.value().data().size());
  std::vector<uint8_t> two_value_expected(array_bytes.begin(), array_bytes.begin() + kTypeSize * 2);
  EXPECT_EQ(two_value_expected, result.value().data().bytes());
  EXPECT_EQ("uint16_t[2]", result.value().type()->GetFullName());
  EXPECT_EQ(kBaseAddress, result.value().source().address());

  // Size 0 should also work.
  called = false;
  CoerceArraySize(eval_context, ptr_value, 0, callback);
  loop().RunUntilNoTasks();
  ASSERT_TRUE(called);
  ASSERT_TRUE(result.ok());
  ASSERT_TRUE(result.value().data().empty());
  EXPECT_EQ("uint16_t[0]", result.value().type()->GetFullName());
  EXPECT_EQ(kBaseAddress, result.value().source().address());
}

TEST_F(ResolveArrayTest, CoerceStaticArraySize) {
  auto eval_context = fxl::MakeRefCounted<MockEvalContext>();

  constexpr uint64_t kBaseAddress = 0x100000;
  constexpr uint32_t kOriginalArraySize = 2;

  // Array holds 3 uint16_t.
  constexpr uint32_t kTypeSize = 2;
  auto elt_type = fxl::MakeRefCounted<BaseType>(BaseType::kBaseTypeUnsigned, kTypeSize, "uint16_t");
  auto array_type = fxl::MakeRefCounted<ArrayType>(elt_type, kOriginalArraySize);

  // The full array in memory including 3 items. The values are 0x1122, 0x3344, 0x5566
  std::vector<uint8_t> array_bytes = {0x22, 0x11, 0x44, 0x33, 0x66, 0x55};
  eval_context->data_provider()->AddMemory(kBaseAddress, array_bytes);
  ExprValue value(array_type, array_bytes, ExprValueSource(kBaseAddress));

  // Source array with 2 elts and a temporary source (not referencing the memory added).
  std::vector<uint8_t> two_elt_bytes(array_bytes.begin(),
                                     array_bytes.begin() + (kOriginalArraySize * kTypeSize));
  ExprValue temp_value(array_type, two_elt_bytes);

  // This callback is used for all examples below.
  bool called = false;
  ErrOrValue result((ExprValue()));
  auto callback = [&called, &result](ErrOrValue value) {
    called = true;
    result = std::move(value);
    debug::MessageLoop::Current()->QuitNow();
  };

  // Shrinking the temporary value should succeed.
  CoerceArraySize(eval_context, temp_value, 1, callback);
  loop().RunUntilNoTasks();
  ASSERT_TRUE(called);
  ASSERT_TRUE(result.ok());
  ASSERT_EQ(2u, result.value().data().size());
  EXPECT_EQ(0x1122, result.value().GetAs<uint16_t>());
  EXPECT_EQ("uint16_t[1]", result.value().type()->GetFullName());

  // Expanding to the same size should work.
  called = false;
  CoerceArraySize(eval_context, temp_value, kOriginalArraySize, callback);
  loop().RunUntilNoTasks();
  ASSERT_TRUE(called);
  ASSERT_TRUE(result.ok());
  EXPECT_EQ(temp_value, result.value());
  EXPECT_EQ("uint16_t[2]", result.value().type()->GetFullName());

  // Expanding the temp value should fail (it references no memory).
  called = false;
  CoerceArraySize(eval_context, temp_value, kOriginalArraySize + 1, callback);
  loop().RunUntilNoTasks();
  ASSERT_TRUE(called);
  ASSERT_FALSE(result.ok());
  EXPECT_EQ("Can not expand array that is not in memory.", result.err().msg());

  // Make an identical value that references the source memory.
  ExprValue mem_value(array_type, two_elt_bytes, ExprValueSource(kBaseAddress));

  // Expanding to the same size should work.
  called = false;
  CoerceArraySize(eval_context, mem_value, kOriginalArraySize + 1, callback);
  loop().RunUntilNoTasks();
  ASSERT_TRUE(called);
  ASSERT_TRUE(result.ok());
  EXPECT_EQ(array_bytes, result.value().data().bytes());
  EXPECT_EQ("uint16_t[3]", result.value().type()->GetFullName());
  EXPECT_EQ(kBaseAddress, result.value().source().address());

  // Expanding beyond the valid memory should fail.
  called = false;
  CoerceArraySize(eval_context, mem_value, kOriginalArraySize + 2, callback);
  loop().RunUntilNoTasks();
  ASSERT_TRUE(called);
  ASSERT_FALSE(result.ok());
  EXPECT_EQ("Array memory not valid.", result.err().msg());

  // Shrinking to empty should also work and it should preserve the source.
  called = false;
  CoerceArraySize(eval_context, mem_value, 0, callback);
  loop().RunUntilNoTasks();
  ASSERT_TRUE(called);
  ASSERT_TRUE(result.ok());
  ASSERT_TRUE(result.value().data().empty());
  EXPECT_EQ("uint16_t[0]", result.value().type()->GetFullName());
  EXPECT_EQ(kBaseAddress, result.value().source().address());
}

}  // namespace zxdb
