//===-- TestOptionValue.cpp --------        -------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "lldb/Interpreter/OptionValues.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"

using namespace lldb_private;

class Callback {
public:
  virtual void Invoke() const {}
  void operator()() const { Invoke(); }
protected:
  ~Callback() = default;
};

class MockCallback final : public Callback {
public:
  MOCK_CONST_METHOD0(Invoke, void());
};

// Test a single-value class.
TEST(OptionValueString, DeepCopy) {
  OptionValueString str;
  str.SetValueFromString("ab");

  MockCallback callback;
  str.SetValueChangedCallback([&callback] { callback(); });
  EXPECT_CALL(callback, Invoke());

  auto copy_sp = str.DeepCopy(nullptr);

  // Test that the base class data members are copied/set correctly.
  ASSERT_TRUE(copy_sp);
  ASSERT_EQ(copy_sp->GetParent().get(), nullptr);
  ASSERT_TRUE(copy_sp->OptionWasSet());
  ASSERT_EQ(copy_sp->GetStringValue(), "ab");

  // Trigger the callback.
  copy_sp->SetValueFromString("c", eVarSetOperationAppend);
  ASSERT_EQ(copy_sp->GetStringValue(), "abc");
}

// Test an aggregate class.
TEST(OptionValueArgs, DeepCopy) {
  OptionValueArgs args;
  args.SetValueFromString("A B");

  MockCallback callback;
  args.SetValueChangedCallback([&callback] { callback(); });
  EXPECT_CALL(callback, Invoke());

  auto copy_sp = args.DeepCopy(nullptr);

  // Test that the base class data members are copied/set correctly.
  ASSERT_TRUE(copy_sp);
  ASSERT_EQ(copy_sp->GetParent(), nullptr);
  ASSERT_TRUE(copy_sp->OptionWasSet());

  auto *args_copy_ptr = copy_sp->GetAsArgs();
  ASSERT_EQ(args_copy_ptr->GetSize(), 2U);
  ASSERT_EQ((*args_copy_ptr)[0]->GetParent(), copy_sp);
  ASSERT_EQ((*args_copy_ptr)[0]->GetStringValue(), "A");
  ASSERT_EQ((*args_copy_ptr)[1]->GetParent(), copy_sp);
  ASSERT_EQ((*args_copy_ptr)[1]->GetStringValue(), "B");

  // Trigger the callback.
  copy_sp->SetValueFromString("C", eVarSetOperationAppend);
  ASSERT_TRUE(args_copy_ptr);
  ASSERT_EQ(args_copy_ptr->GetSize(), 3U);
  ASSERT_EQ((*args_copy_ptr)[2]->GetStringValue(), "C");
}

class TestProperties : public OptionValueProperties {
public:
  static std::shared_ptr<TestProperties> CreateGlobal() {
    auto props_sp = std::make_shared<TestProperties>();
    const bool is_global = false;

    auto dict_sp = std::make_shared<OptionValueDictionary>(1 << eTypeUInt64);
    props_sp->AppendProperty(ConstString("dict"), ConstString(), is_global,
                             dict_sp);

    auto file_list_sp = std::make_shared<OptionValueFileSpecList>();
    props_sp->AppendProperty(ConstString("file-list"), ConstString(), is_global,
                             file_list_sp);
    return props_sp;
  }

  void SetDictionaryChangedCallback(const MockCallback &callback) {
    SetValueChangedCallback(m_dict_index, [&callback] { callback(); });
  }

  void SetFileListChangedCallback(const MockCallback &callback) {
    SetValueChangedCallback(m_file_list_index, [&callback] { callback(); });
  }

  OptionValueDictionary *GetDictionary() {
    return GetPropertyAtIndexAsOptionValueDictionary(nullptr, m_dict_index);
  }

  OptionValueFileSpecList *GetFileList() {
    return GetPropertyAtIndexAsOptionValueFileSpecList(nullptr, true,
                                                       m_file_list_index);
  }

private:
  lldb::OptionValueSP Clone() const {
    return std::make_shared<TestProperties>(*this);
  }

  uint32_t m_dict_index = 0;
  uint32_t m_file_list_index = 1;
};

// Test a user-defined propery class.
TEST(TestProperties, DeepCopy) {
  auto props_sp = TestProperties::CreateGlobal();
  props_sp->GetDictionary()->SetValueFromString("A=1 B=2");
  props_sp->GetFileList()->SetValueFromString("path/to/file");

  MockCallback callback;
  props_sp->SetDictionaryChangedCallback(callback);
  props_sp->SetFileListChangedCallback(callback);
  EXPECT_CALL(callback, Invoke()).Times(2);

  auto copy_sp = props_sp->DeepCopy(nullptr);

  // Test that the base class data members are copied/set correctly.
  ASSERT_TRUE(copy_sp);
  ASSERT_EQ(copy_sp->GetParent(), nullptr);

  // This cast is safe only if the class overrides Clone().
  auto *props_copy_ptr = static_cast<TestProperties *>(copy_sp.get());
  ASSERT_TRUE(props_copy_ptr);

  // Test the first child.
  auto dict_copy_ptr = props_copy_ptr->GetDictionary();
  ASSERT_TRUE(dict_copy_ptr);
  ASSERT_EQ(dict_copy_ptr->GetParent(), copy_sp);
  ASSERT_TRUE(dict_copy_ptr->OptionWasSet());
  ASSERT_EQ(dict_copy_ptr->GetNumValues(), 2U);

  auto value_ptr = dict_copy_ptr->GetValueForKey(ConstString("A"));
  ASSERT_TRUE(value_ptr);
  ASSERT_EQ(value_ptr->GetParent().get(), dict_copy_ptr);
  ASSERT_EQ(value_ptr->GetUInt64Value(), 1U);

  value_ptr = dict_copy_ptr->GetValueForKey(ConstString("B"));
  ASSERT_TRUE(value_ptr);
  ASSERT_EQ(value_ptr->GetParent().get(), dict_copy_ptr);
  ASSERT_EQ(value_ptr->GetUInt64Value(), 2U);

  // Test the second child.
  auto file_list_copy_ptr = props_copy_ptr->GetFileList();
  ASSERT_TRUE(file_list_copy_ptr);
  ASSERT_EQ(file_list_copy_ptr->GetParent(), copy_sp);
  ASSERT_TRUE(file_list_copy_ptr->OptionWasSet());

  auto file_list_copy = file_list_copy_ptr->GetCurrentValue();
  ASSERT_EQ(file_list_copy.GetSize(), 1U);
  ASSERT_EQ(file_list_copy.GetFileSpecAtIndex(0), FileSpec("path/to/file"));

  // Trigger the callback first time.
  dict_copy_ptr->SetValueFromString("C=3", eVarSetOperationAppend);

  // Trigger the callback second time.
  file_list_copy_ptr->SetValueFromString("0 another/path", eVarSetOperationReplace);
}
