//===-- PythonDataObjectsTests.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 "Plugins/ScriptInterpreter/Python/lldb-python.h"
#include "gtest/gtest.h"

#include "Plugins/ScriptInterpreter/Python/PythonDataObjects.h"
#include "Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h"
#include "TestingSupport/SubsystemRAII.h"
#include "lldb/Host/File.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/lldb-enumerations.h"
#include "llvm/Testing/Support/Error.h"

#include "PythonTestSuite.h"

#include <variant>

using namespace lldb_private;
using namespace lldb_private::python;
using llvm::Expected;

class PythonDataObjectsTest : public PythonTestSuite {
  SubsystemRAII<FileSystem> subsystems;

public:
  void SetUp() override {
    PythonTestSuite::SetUp();

    m_sys_module = unwrapIgnoringErrors(PythonModule::Import("sys"));
    m_main_module = PythonModule::MainModule();
    m_builtins_module = PythonModule::BuiltinsModule();
  }

  void TearDown() override {
    m_sys_module.Reset();
    m_main_module.Reset();
    m_builtins_module.Reset();

    PythonTestSuite::TearDown();
  }

protected:
  PythonModule m_sys_module;
  PythonModule m_main_module;
  PythonModule m_builtins_module;
};

TEST_F(PythonDataObjectsTest, TestOwnedReferences) {
  // After creating a new object, the refcount should be >= 1
  PyObject *obj = PyBytes_FromString("foo");
  Py_ssize_t original_refcnt = Py_REFCNT(obj);
  EXPECT_LE(1, original_refcnt);

  // If we take an owned reference, the refcount should be the same
  PythonObject owned(PyRefType::Owned, obj);
  Py_ssize_t owned_refcnt = Py_REFCNT(owned.get());
  EXPECT_EQ(original_refcnt, owned_refcnt);

  // Take another reference and verify that the refcount increases by 1
  PythonObject strong_ref(owned);
  Py_ssize_t strong_refcnt = Py_REFCNT(strong_ref.get());
  EXPECT_EQ(original_refcnt + 1, strong_refcnt);

  // If we reset the first one, the refcount should be the original value.
  owned.Reset();
  strong_refcnt = Py_REFCNT(strong_ref.get());
  EXPECT_EQ(original_refcnt, strong_refcnt);
}

TEST_F(PythonDataObjectsTest, TestResetting) {
  PythonDictionary dict(PyInitialValue::Empty);

  PyObject *new_dict = PyDict_New();
  dict = Take<PythonDictionary>(new_dict);
  EXPECT_EQ(new_dict, dict.get());

  dict = Take<PythonDictionary>(PyDict_New());
  EXPECT_NE(nullptr, dict.get());
  dict.Reset();
  EXPECT_EQ(nullptr, dict.get());
}

TEST_F(PythonDataObjectsTest, TestBorrowedReferences) {
  PythonByteArray byte_value(PyRefType::Owned,
                             PyByteArray_FromStringAndSize("foo", 3));
  Py_ssize_t original_refcnt = Py_REFCNT(byte_value.get());
  EXPECT_LE(1, original_refcnt);

  PythonByteArray borrowed_byte(PyRefType::Borrowed, byte_value.get());
  Py_ssize_t borrowed_refcnt = Py_REFCNT(borrowed_byte.get());

  EXPECT_EQ(original_refcnt + 1, borrowed_refcnt);
}

TEST_F(PythonDataObjectsTest, TestGlobalNameResolutionNoDot) {
  PythonObject sys_module = m_main_module.ResolveName("sys");
  EXPECT_EQ(m_sys_module.get(), sys_module.get());
  EXPECT_TRUE(sys_module.IsAllocated());
  EXPECT_TRUE(PythonModule::Check(sys_module.get()));
}

TEST_F(PythonDataObjectsTest, TestModuleNameResolutionNoDot) {
  PythonObject sys_path = m_sys_module.ResolveName("path");
  PythonObject sys_version_info = m_sys_module.ResolveName("version_info");
  EXPECT_TRUE(sys_path.IsAllocated());
  EXPECT_TRUE(sys_version_info.IsAllocated());

  EXPECT_TRUE(PythonList::Check(sys_path.get()));
}

TEST_F(PythonDataObjectsTest, TestTypeNameResolutionNoDot) {
  PythonObject sys_version_info = m_sys_module.ResolveName("version_info");

  PythonObject version_info_type(PyRefType::Owned,
                                 PyObject_Type(sys_version_info.get()));
  EXPECT_TRUE(version_info_type.IsAllocated());
  PythonObject major_version_field = version_info_type.ResolveName("major");
  EXPECT_TRUE(major_version_field.IsAllocated());
}

TEST_F(PythonDataObjectsTest, TestInstanceNameResolutionNoDot) {
  PythonObject sys_version_info = m_sys_module.ResolveName("version_info");
  PythonObject major_version_field = sys_version_info.ResolveName("major");
  PythonObject minor_version_field = sys_version_info.ResolveName("minor");

  EXPECT_TRUE(major_version_field.IsAllocated());
  EXPECT_TRUE(minor_version_field.IsAllocated());

  auto major_version_value = As<long long>(major_version_field);
  auto minor_version_value = As<long long>(minor_version_field);

  EXPECT_THAT_EXPECTED(major_version_value, llvm::HasValue(PY_MAJOR_VERSION));
  EXPECT_THAT_EXPECTED(minor_version_value, llvm::HasValue(PY_MINOR_VERSION));
}

TEST_F(PythonDataObjectsTest, TestGlobalNameResolutionWithDot) {
  PythonObject sys_path = m_main_module.ResolveName("sys.path");
  EXPECT_TRUE(sys_path.IsAllocated());
  EXPECT_TRUE(PythonList::Check(sys_path.get()));

  auto version_major =
      As<long long>(m_main_module.ResolveName("sys.version_info.major"));

  auto version_minor =
      As<long long>(m_main_module.ResolveName("sys.version_info.minor"));

  EXPECT_THAT_EXPECTED(version_major, llvm::HasValue(PY_MAJOR_VERSION));
  EXPECT_THAT_EXPECTED(version_minor, llvm::HasValue(PY_MINOR_VERSION));
}

TEST_F(PythonDataObjectsTest, TestDictionaryResolutionWithDot) {
  // Make up a custom dictionary with "sys" pointing to the `sys` module.
  PythonDictionary dict(PyInitialValue::Empty);
  dict.SetItemForKey(PythonString("sys"), m_sys_module);

  // Now use that dictionary to resolve `sys.version_info.major`
  auto version_major = As<long long>(
      PythonObject::ResolveNameWithDictionary("sys.version_info.major", dict));

  auto version_minor = As<long long>(
      PythonObject::ResolveNameWithDictionary("sys.version_info.minor", dict));

  EXPECT_THAT_EXPECTED(version_major, llvm::HasValue(PY_MAJOR_VERSION));
  EXPECT_THAT_EXPECTED(version_minor, llvm::HasValue(PY_MINOR_VERSION));
}

TEST_F(PythonDataObjectsTest, TestPythonInteger) {
  // Test that integers behave correctly when wrapped by a PythonInteger.

  // Verify that `PythonInteger` works correctly when given a PyLong object.
  PyObject *py_long = PyLong_FromLong(12);
  EXPECT_TRUE(PythonInteger::Check(py_long));
  PythonInteger python_long(PyRefType::Owned, py_long);
  EXPECT_EQ(PyObjectType::Integer, python_long.GetObjectType());

  // Verify that you can reset the value and that it is reflected properly.
  python_long.SetInteger(40);
  auto e = As<long long>(python_long);
  EXPECT_THAT_EXPECTED(e, llvm::HasValue(40));

  // Test that creating a `PythonInteger` object works correctly with the
  // int constructor.
  PythonInteger constructed_int(7);
  auto value = As<long long>(constructed_int);
  EXPECT_THAT_EXPECTED(value, llvm::HasValue(7));
}

TEST_F(PythonDataObjectsTest, TestPythonBoolean) {
  // Test PythonBoolean constructed from Py_True
  EXPECT_TRUE(PythonBoolean::Check(Py_True));
  PythonBoolean python_true(PyRefType::Owned, Py_True);
  EXPECT_EQ(PyObjectType::Boolean, python_true.GetObjectType());

  // Test PythonBoolean constructed from Py_False
  EXPECT_TRUE(PythonBoolean::Check(Py_False));
  PythonBoolean python_false(PyRefType::Owned, Py_False);
  EXPECT_EQ(PyObjectType::Boolean, python_false.GetObjectType());

  auto test_from_long = [](long value) {
    PyObject *py_bool = PyBool_FromLong(value);
    EXPECT_TRUE(PythonBoolean::Check(py_bool));
    PythonBoolean python_boolean(PyRefType::Owned, py_bool);
    EXPECT_EQ(PyObjectType::Boolean, python_boolean.GetObjectType());
    EXPECT_EQ(bool(value), python_boolean.GetValue());
  };

  // Test PythonBoolean constructed from long integer values.
  test_from_long(0);  // Test 'false' value.
  test_from_long(1);  // Test 'true' value.
  test_from_long(~0); // Any value != 0 is 'true'.
}

TEST_F(PythonDataObjectsTest, TestPythonBytes) {
  static const char *test_bytes = "PythonDataObjectsTest::TestPythonBytes";
  PyObject *py_bytes = PyBytes_FromString(test_bytes);
  EXPECT_TRUE(PythonBytes::Check(py_bytes));
  PythonBytes python_bytes(PyRefType::Owned, py_bytes);

  EXPECT_FALSE(PythonString::Check(py_bytes));
  EXPECT_EQ(PyObjectType::Bytes, python_bytes.GetObjectType());

  llvm::ArrayRef<uint8_t> bytes = python_bytes.GetBytes();
  EXPECT_EQ(bytes.size(), strlen(test_bytes));
  EXPECT_EQ(0, ::memcmp(bytes.data(), test_bytes, bytes.size()));
}

TEST_F(PythonDataObjectsTest, TestPythonByteArray) {
  static const char *test_bytes = "PythonDataObjectsTest::TestPythonByteArray";
  llvm::StringRef orig_bytes(test_bytes);
  PyObject *py_bytes =
      PyByteArray_FromStringAndSize(test_bytes, orig_bytes.size());
  EXPECT_TRUE(PythonByteArray::Check(py_bytes));
  PythonByteArray python_bytes(PyRefType::Owned, py_bytes);
  EXPECT_EQ(PyObjectType::ByteArray, python_bytes.GetObjectType());

  llvm::ArrayRef<uint8_t> after_bytes = python_bytes.GetBytes();
  EXPECT_EQ(after_bytes.size(), orig_bytes.size());
  EXPECT_EQ(0, ::memcmp(orig_bytes.data(), test_bytes, orig_bytes.size()));
}

TEST_F(PythonDataObjectsTest, TestPythonString) {
  // Test that strings behave correctly when wrapped by a PythonString.

  static const char *test_string = "PythonDataObjectsTest::TestPythonString1";
  static const char *test_string2 = "PythonDataObjectsTest::TestPythonString2";

  // Verify that `PythonString` works correctly when given a PyUnicode object.
  PyObject *py_unicode = PyUnicode_FromString(test_string);
  EXPECT_TRUE(PythonString::Check(py_unicode));
  PythonString python_unicode(PyRefType::Owned, py_unicode);
  EXPECT_EQ(PyObjectType::String, python_unicode.GetObjectType());
  EXPECT_STREQ(test_string, python_unicode.GetString().data());

  // Test that creating a `PythonString` object works correctly with the
  // string constructor
  PythonString constructed_string(test_string2);
  EXPECT_EQ(test_string2, constructed_string.GetString());
}

TEST_F(PythonDataObjectsTest, TestPythonStringToStr) {
  const char *GetString = "PythonDataObjectsTest::TestPythonStringToStr";

  PythonString str(GetString);
  EXPECT_EQ(GetString, str.GetString());

  PythonString str_str = str.Str();
  EXPECT_EQ(GetString, str_str.GetString());
}

TEST_F(PythonDataObjectsTest, TestPythonIntegerToStr) {}

TEST_F(PythonDataObjectsTest, TestPythonIntegerToStructuredUnsignedInteger) {
  PythonInteger integer(7);
  auto int_sp = integer.CreateStructuredInteger();
  EXPECT_TRUE(
      std::holds_alternative<StructuredData::UnsignedIntegerSP>(int_sp));
  StructuredData::UnsignedIntegerSP uint_sp =
      std::get<StructuredData::UnsignedIntegerSP>(int_sp);
  EXPECT_EQ(7U, uint_sp->GetValue());
}

TEST_F(PythonDataObjectsTest, TestPythonIntegerToStructuredSignedInteger) {
  PythonInteger integer(-42);
  auto int_sp = integer.CreateStructuredInteger();
  EXPECT_TRUE(std::holds_alternative<StructuredData::SignedIntegerSP>(int_sp));
  StructuredData::SignedIntegerSP sint_sp =
      std::get<StructuredData::SignedIntegerSP>(int_sp);
  EXPECT_EQ(-42, sint_sp->GetValue());
}

TEST_F(PythonDataObjectsTest, TestPythonStringToStructuredString) {
  static const char *test_string =
      "PythonDataObjectsTest::TestPythonStringToStructuredString";
  PythonString constructed_string(test_string);
  auto string_sp = constructed_string.CreateStructuredString();
  EXPECT_EQ(test_string, string_sp->GetStringValue());
}

TEST_F(PythonDataObjectsTest, TestPythonListValueEquality) {
  // Test that a list which is built through the native
  // Python API behaves correctly when wrapped by a PythonList.
  static const unsigned list_size = 2;
  static const long long_value0 = 5;
  static const char *const string_value1 = "String Index 1";

  PyObject *py_list = PyList_New(2);
  EXPECT_TRUE(PythonList::Check(py_list));
  PythonList list(PyRefType::Owned, py_list);

  PythonObject list_items[list_size];
  list_items[0] = PythonInteger(long_value0);
  list_items[1] = PythonString(string_value1);

  for (unsigned i = 0; i < list_size; ++i)
    list.SetItemAtIndex(i, list_items[i]);

  EXPECT_EQ(list_size, list.GetSize());
  EXPECT_EQ(PyObjectType::List, list.GetObjectType());

  // Verify that the values match
  PythonObject chk_value1 = list.GetItemAtIndex(0);
  PythonObject chk_value2 = list.GetItemAtIndex(1);
  EXPECT_TRUE(PythonInteger::Check(chk_value1.get()));
  EXPECT_TRUE(PythonString::Check(chk_value2.get()));

  PythonInteger chk_int(PyRefType::Borrowed, chk_value1.get());
  PythonString chk_str(PyRefType::Borrowed, chk_value2.get());

  auto chkint = As<long long>(chk_value1);
  ASSERT_THAT_EXPECTED(chkint, llvm::HasValue(long_value0));
  EXPECT_EQ(string_value1, chk_str.GetString());
}

TEST_F(PythonDataObjectsTest, TestPythonListManipulation) {
  // Test that manipulation of a PythonList behaves correctly when
  // wrapped by a PythonDictionary.

  static const long long_value0 = 5;
  static const char *const string_value1 = "String Index 1";

  PythonList list(PyInitialValue::Empty);
  PythonInteger integer(long_value0);
  PythonString string(string_value1);

  list.AppendItem(integer);
  list.AppendItem(string);
  EXPECT_EQ(2U, list.GetSize());

  // Verify that the values match
  PythonObject chk_value1 = list.GetItemAtIndex(0);
  PythonObject chk_value2 = list.GetItemAtIndex(1);
  EXPECT_TRUE(PythonInteger::Check(chk_value1.get()));
  EXPECT_TRUE(PythonString::Check(chk_value2.get()));

  PythonInteger chk_int(PyRefType::Borrowed, chk_value1.get());
  PythonString chk_str(PyRefType::Borrowed, chk_value2.get());

  auto e = As<long long>(chk_int);
  EXPECT_THAT_EXPECTED(e, llvm::HasValue(long_value0));
  EXPECT_EQ(string_value1, chk_str.GetString());
}

TEST_F(PythonDataObjectsTest, TestPythonListToStructuredList) {
  static const long long_value0 = 5;
  static const char *const string_value1 = "String Index 1";

  PythonList list(PyInitialValue::Empty);
  list.AppendItem(PythonInteger(long_value0));
  list.AppendItem(PythonString(string_value1));

  auto array_sp = list.CreateStructuredArray();
  EXPECT_EQ(lldb::eStructuredDataTypeInteger,
            array_sp->GetItemAtIndex(0)->GetType());
  EXPECT_EQ(lldb::eStructuredDataTypeString,
            array_sp->GetItemAtIndex(1)->GetType());

  auto int_sp = array_sp->GetItemAtIndex(0)->GetAsUnsignedInteger();
  auto string_sp = array_sp->GetItemAtIndex(1)->GetAsString();

  EXPECT_EQ(long_value0, long(int_sp->GetValue()));
  EXPECT_EQ(string_value1, string_sp->GetValue());
}

TEST_F(PythonDataObjectsTest, TestPythonTupleSize) {
  PythonTuple tuple(PyInitialValue::Empty);
  EXPECT_EQ(0U, tuple.GetSize());

  tuple = PythonTuple(3);
  EXPECT_EQ(3U, tuple.GetSize());
}

TEST_F(PythonDataObjectsTest, TestPythonTupleValues) {
  PythonTuple tuple(3);

  PythonInteger int_value(1);
  PythonString string_value("Test");
  PythonObject none_value(PyRefType::Borrowed, Py_None);

  tuple.SetItemAtIndex(0, int_value);
  tuple.SetItemAtIndex(1, string_value);
  tuple.SetItemAtIndex(2, none_value);

  EXPECT_EQ(tuple.GetItemAtIndex(0).get(), int_value.get());
  EXPECT_EQ(tuple.GetItemAtIndex(1).get(), string_value.get());
  EXPECT_EQ(tuple.GetItemAtIndex(2).get(), none_value.get());
}

TEST_F(PythonDataObjectsTest, TestPythonTupleInitializerList) {
  PythonInteger int_value(1);
  PythonString string_value("Test");
  PythonObject none_value(PyRefType::Borrowed, Py_None);
  PythonTuple tuple{int_value, string_value, none_value};
  EXPECT_EQ(3U, tuple.GetSize());

  EXPECT_EQ(tuple.GetItemAtIndex(0).get(), int_value.get());
  EXPECT_EQ(tuple.GetItemAtIndex(1).get(), string_value.get());
  EXPECT_EQ(tuple.GetItemAtIndex(2).get(), none_value.get());
}

TEST_F(PythonDataObjectsTest, TestPythonTupleInitializerList2) {
  PythonInteger int_value(1);
  PythonString string_value("Test");
  PythonObject none_value(PyRefType::Borrowed, Py_None);

  PythonTuple tuple{int_value.get(), string_value.get(), none_value.get()};
  EXPECT_EQ(3U, tuple.GetSize());

  EXPECT_EQ(tuple.GetItemAtIndex(0).get(), int_value.get());
  EXPECT_EQ(tuple.GetItemAtIndex(1).get(), string_value.get());
  EXPECT_EQ(tuple.GetItemAtIndex(2).get(), none_value.get());
}

TEST_F(PythonDataObjectsTest, TestPythonTupleToStructuredList) {
  PythonInteger int_value(1);
  PythonString string_value("Test");

  PythonTuple tuple{int_value.get(), string_value.get()};

  auto array_sp = tuple.CreateStructuredArray();
  EXPECT_EQ(tuple.GetSize(), array_sp->GetSize());
  EXPECT_EQ(lldb::eStructuredDataTypeInteger,
            array_sp->GetItemAtIndex(0)->GetType());
  EXPECT_EQ(lldb::eStructuredDataTypeString,
            array_sp->GetItemAtIndex(1)->GetType());
}

TEST_F(PythonDataObjectsTest, TestPythonDictionaryValueEquality) {
  // Test that a dictionary which is built through the native
  // Python API behaves correctly when wrapped by a PythonDictionary.
  static const unsigned dict_entries = 2;
  const char *key_0 = "Key 0";
  int key_1 = 1;
  const int value_0 = 0;
  const char *value_1 = "Value 1";

  PythonObject py_keys[dict_entries];
  PythonObject py_values[dict_entries];

  py_keys[0] = PythonString(key_0);
  py_keys[1] = PythonInteger(key_1);
  py_values[0] = PythonInteger(value_0);
  py_values[1] = PythonString(value_1);

  PyObject *py_dict = PyDict_New();
  EXPECT_TRUE(PythonDictionary::Check(py_dict));
  PythonDictionary dict(PyRefType::Owned, py_dict);

  for (unsigned i = 0; i < dict_entries; ++i)
    PyDict_SetItem(py_dict, py_keys[i].get(), py_values[i].get());
  EXPECT_EQ(dict.GetSize(), dict_entries);
  EXPECT_EQ(PyObjectType::Dictionary, dict.GetObjectType());

  // Verify that the values match
  PythonObject chk_value1 = dict.GetItemForKey(py_keys[0]);
  PythonObject chk_value2 = dict.GetItemForKey(py_keys[1]);
  EXPECT_TRUE(PythonInteger::Check(chk_value1.get()));
  EXPECT_TRUE(PythonString::Check(chk_value2.get()));

  PythonString chk_str(PyRefType::Borrowed, chk_value2.get());
  auto chkint = As<long long>(chk_value1);

  EXPECT_THAT_EXPECTED(chkint, llvm::HasValue(value_0));
  EXPECT_EQ(value_1, chk_str.GetString());
}

TEST_F(PythonDataObjectsTest, TestPythonDictionaryManipulation) {
  // Test that manipulation of a dictionary behaves correctly when wrapped
  // by a PythonDictionary.
  static const unsigned dict_entries = 2;

  const char *const key_0 = "Key 0";
  const char *const key_1 = "Key 1";
  const long value_0 = 1;
  const char *const value_1 = "Value 1";

  PythonString keys[dict_entries];
  PythonObject values[dict_entries];

  keys[0] = PythonString(key_0);
  keys[1] = PythonString(key_1);
  values[0] = PythonInteger(value_0);
  values[1] = PythonString(value_1);

  PythonDictionary dict(PyInitialValue::Empty);
  for (int i = 0; i < 2; ++i)
    dict.SetItemForKey(keys[i], values[i]);

  EXPECT_EQ(dict_entries, dict.GetSize());
  EXPECT_FALSE(dict.HasKey("not_in_dict"));
  EXPECT_TRUE(dict.HasKey(key_0));
  EXPECT_TRUE(dict.HasKey(key_1));

  // Verify that the keys and values match
  PythonObject chk_value1 = dict.GetItemForKey(keys[0]);
  PythonObject chk_value2 = dict.GetItemForKey(keys[1]);
  EXPECT_TRUE(PythonInteger::Check(chk_value1.get()));
  EXPECT_TRUE(PythonString::Check(chk_value2.get()));

  auto chkint = As<long long>(chk_value1);
  PythonString chk_str(PyRefType::Borrowed, chk_value2.get());

  EXPECT_THAT_EXPECTED(chkint, llvm::HasValue(value_0));
  EXPECT_EQ(value_1, chk_str.GetString());
}

TEST_F(PythonDataObjectsTest, TestPythonDictionaryToStructuredDictionary) {
  static const char *const string_key0 = "String Key 0";
  static const char *const string_key1 = "String Key 1";

  static const char *const string_value0 = "String Value 0";
  static const long int_value1 = 7;

  PythonDictionary dict(PyInitialValue::Empty);
  dict.SetItemForKey(PythonString(string_key0), PythonString(string_value0));
  dict.SetItemForKey(PythonString(string_key1), PythonInteger(int_value1));

  auto dict_sp = dict.CreateStructuredDictionary();
  EXPECT_EQ(2U, dict_sp->GetSize());

  EXPECT_TRUE(dict_sp->HasKey(string_key0));
  EXPECT_TRUE(dict_sp->HasKey(string_key1));

  auto string_sp = dict_sp->GetValueForKey(string_key0)->GetAsString();
  auto int_sp = dict_sp->GetValueForKey(string_key1)->GetAsUnsignedInteger();

  EXPECT_EQ(string_value0, string_sp->GetValue());
  EXPECT_EQ(int_value1, long(int_sp->GetValue()));
}

TEST_F(PythonDataObjectsTest, TestPythonCallableCheck) {
  PythonObject sys_exc_info = m_sys_module.ResolveName("exc_info");
  PythonObject none(PyRefType::Borrowed, Py_None);

  EXPECT_TRUE(PythonCallable::Check(sys_exc_info.get()));
  EXPECT_FALSE(PythonCallable::Check(none.get()));
}

TEST_F(PythonDataObjectsTest, TestPythonCallableInvoke) {
  auto list = m_builtins_module.ResolveName("list").AsType<PythonCallable>();
  PythonInteger one(1);
  PythonString two("two");
  PythonTuple three = {one, two};

  PythonTuple tuple_to_convert = {one, two, three};
  PythonObject result = list({tuple_to_convert});

  EXPECT_TRUE(PythonList::Check(result.get()));
  auto list_result = result.AsType<PythonList>();
  EXPECT_EQ(3U, list_result.GetSize());
  EXPECT_EQ(one.get(), list_result.GetItemAtIndex(0).get());
  EXPECT_EQ(two.get(), list_result.GetItemAtIndex(1).get());
  EXPECT_EQ(three.get(), list_result.GetItemAtIndex(2).get());
}

TEST_F(PythonDataObjectsTest, TestPythonFile) {
  auto file = FileSystem::Instance().Open(FileSpec(FileSystem::DEV_NULL),
                                          File::eOpenOptionReadOnly);
  ASSERT_THAT_EXPECTED(file, llvm::Succeeded());
  auto py_file = PythonFile::FromFile(*file.get(), "r");
  ASSERT_THAT_EXPECTED(py_file, llvm::Succeeded());
  EXPECT_TRUE(PythonFile::Check(py_file.get().get()));
}

TEST_F(PythonDataObjectsTest, TestObjectAttributes) {
  PythonInteger py_int(42);
  EXPECT_TRUE(py_int.HasAttribute("numerator"));
  EXPECT_FALSE(py_int.HasAttribute("this_should_not_exist"));

  auto numerator_attr = As<long long>(py_int.GetAttributeValue("numerator"));

  EXPECT_THAT_EXPECTED(numerator_attr, llvm::HasValue(42));
}

TEST_F(PythonDataObjectsTest, TestExtractingUInt64ThroughStructuredData) {
  // Make up a custom dictionary with "sys" pointing to the `sys` module.
  const char *key_name = "addr";
  const uint64_t value = 0xf000000000000000ull;
  PythonDictionary python_dict(PyInitialValue::Empty);
  PythonInteger python_ull_value(PyRefType::Owned,
                                 PyLong_FromUnsignedLongLong(value));
  python_dict.SetItemForKey(PythonString(key_name), python_ull_value);
  StructuredData::ObjectSP structured_data_sp =
      python_dict.CreateStructuredObject();
  EXPECT_TRUE((bool)structured_data_sp);
  if (structured_data_sp) {
    StructuredData::Dictionary *structured_dict_ptr =
        structured_data_sp->GetAsDictionary();
    EXPECT_TRUE(structured_dict_ptr != nullptr);
    if (structured_dict_ptr) {
      StructuredData::ObjectSP structured_addr_value_sp =
          structured_dict_ptr->GetValueForKey(key_name);
      EXPECT_TRUE((bool)structured_addr_value_sp);
      const uint64_t extracted_value =
          structured_addr_value_sp->GetUnsignedIntegerValue(123);
      EXPECT_TRUE(extracted_value == value);
    }
  }
}

TEST_F(PythonDataObjectsTest, TestCallable) {

  PythonDictionary globals(PyInitialValue::Empty);
  auto builtins = PythonModule::BuiltinsModule();
  llvm::Error error = globals.SetItem("__builtins__", builtins);
  ASSERT_FALSE(error);

  {
    PyObject *o = PyRun_String("lambda x : x", Py_eval_input, globals.get(),
                               globals.get());
    ASSERT_FALSE(o == NULL);
    auto lambda = Take<PythonCallable>(o);
    auto arginfo = lambda.GetArgInfo();
    ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
    EXPECT_EQ(arginfo.get().max_positional_args, 1u);
  }

  {
    PyObject *o = PyRun_String("lambda x,y=0: x", Py_eval_input, globals.get(),
                               globals.get());
    ASSERT_FALSE(o == NULL);
    auto lambda = Take<PythonCallable>(o);
    auto arginfo = lambda.GetArgInfo();
    ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
    EXPECT_EQ(arginfo.get().max_positional_args, 2u);
  }

  {
    PyObject *o = PyRun_String("lambda x,y=0, **kw: x", Py_eval_input,
                               globals.get(), globals.get());
    ASSERT_FALSE(o == NULL);
    auto lambda = Take<PythonCallable>(o);
    auto arginfo = lambda.GetArgInfo();
    ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
    EXPECT_EQ(arginfo.get().max_positional_args, 2u);
  }

  {
    PyObject *o = PyRun_String("lambda x,y,*a: x", Py_eval_input, globals.get(),
                               globals.get());
    ASSERT_FALSE(o == NULL);
    auto lambda = Take<PythonCallable>(o);
    auto arginfo = lambda.GetArgInfo();
    ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
    EXPECT_EQ(arginfo.get().max_positional_args,
              PythonCallable::ArgInfo::UNBOUNDED);
  }

  {
    PyObject *o = PyRun_String("lambda x,y,*a,**kw: x", Py_eval_input,
                               globals.get(), globals.get());
    ASSERT_FALSE(o == NULL);
    auto lambda = Take<PythonCallable>(o);
    auto arginfo = lambda.GetArgInfo();
    ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
    EXPECT_EQ(arginfo.get().max_positional_args,
              PythonCallable::ArgInfo::UNBOUNDED);
  }

  {
    const char *script = R"(
class Foo:
  def bar(self, x):
     return x
  @classmethod
  def classbar(cls, x):
     return x
  @staticmethod
  def staticbar(x):
     return x
  def __call__(self, x):
     return x
obj = Foo()
bar_bound   = Foo().bar
bar_class   = Foo().classbar
bar_static  = Foo().staticbar
bar_unbound = Foo.bar


class OldStyle:
  def __init__(self, one, two, three):
    pass

class NewStyle(object):
  def __init__(self, one, two, three):
    pass

)";
    PyObject *o =
        PyRun_String(script, Py_file_input, globals.get(), globals.get());
    ASSERT_FALSE(o == NULL);
    Take<PythonObject>(o);

    auto bar_bound = As<PythonCallable>(globals.GetItem("bar_bound"));
    ASSERT_THAT_EXPECTED(bar_bound, llvm::Succeeded());
    auto arginfo = bar_bound.get().GetArgInfo();
    ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
    EXPECT_EQ(arginfo.get().max_positional_args, 1u);

    auto bar_unbound = As<PythonCallable>(globals.GetItem("bar_unbound"));
    ASSERT_THAT_EXPECTED(bar_unbound, llvm::Succeeded());
    arginfo = bar_unbound.get().GetArgInfo();
    ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
    EXPECT_EQ(arginfo.get().max_positional_args, 2u);

    auto bar_class = As<PythonCallable>(globals.GetItem("bar_class"));
    ASSERT_THAT_EXPECTED(bar_class, llvm::Succeeded());
    arginfo = bar_class.get().GetArgInfo();
    ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
    EXPECT_EQ(arginfo.get().max_positional_args, 1u);

    auto bar_static = As<PythonCallable>(globals.GetItem("bar_static"));
    ASSERT_THAT_EXPECTED(bar_static, llvm::Succeeded());
    arginfo = bar_static.get().GetArgInfo();
    ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
    EXPECT_EQ(arginfo.get().max_positional_args, 1u);

    auto obj = As<PythonCallable>(globals.GetItem("obj"));
    ASSERT_THAT_EXPECTED(obj, llvm::Succeeded());
    arginfo = obj.get().GetArgInfo();
    ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
    EXPECT_EQ(arginfo.get().max_positional_args, 1u);

    auto oldstyle = As<PythonCallable>(globals.GetItem("OldStyle"));
    ASSERT_THAT_EXPECTED(oldstyle, llvm::Succeeded());
    arginfo = oldstyle.get().GetArgInfo();
    ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
    EXPECT_EQ(arginfo.get().max_positional_args, 3u);

    auto newstyle = As<PythonCallable>(globals.GetItem("NewStyle"));
    ASSERT_THAT_EXPECTED(newstyle, llvm::Succeeded());
    arginfo = newstyle.get().GetArgInfo();
    ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
    EXPECT_EQ(arginfo.get().max_positional_args, 3u);
  }

  {
    auto builtins = PythonModule::BuiltinsModule();
    auto hex = As<PythonCallable>(builtins.GetAttribute("hex"));
    ASSERT_THAT_EXPECTED(hex, llvm::Succeeded());
    auto arginfo = hex.get().GetArgInfo();
    ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
    EXPECT_EQ(arginfo.get().max_positional_args, 1u);
  }
}

TEST_F(PythonDataObjectsTest, TestScript) {

  static const char script[] = R"(
def factorial(n):
  if n > 1:
    return n * factorial(n-1)
  else:
    return 1;
main = factorial
)";

  PythonScript factorial(script);

  EXPECT_THAT_EXPECTED(As<long long>(factorial(5ll)), llvm::HasValue(120));
}

TEST_F(PythonDataObjectsTest, TestExceptions) {

  static const char script[] = R"(
def foo():
  return bar()
def bar():
  return baz()
def baz():
  return 1 / 0
main = foo
)";

  PythonScript foo(script);

  EXPECT_THAT_EXPECTED(
      foo(), llvm::Failed<PythonException>(testing::Property(
                 &PythonException::ReadBacktrace,
                 testing::AllOf(testing::ContainsRegex("line 3, in foo"),
                                testing::ContainsRegex("line 5, in bar"),
                                testing::ContainsRegex("line 7, in baz"),
                                testing::ContainsRegex("ZeroDivisionError")))));

#if !((defined(_WIN32) || defined(_WIN64)) &&                                  \
      (defined(__aarch64__) || defined(_M_ARM64)))

  static const char script2[] = R"(
class MyError(Exception):
  def __str__(self):
    return self.my_message

def main():
  raise MyError("lol")

)";

  PythonScript lol(script2);

  EXPECT_THAT_EXPECTED(
      lol(),
      llvm::Failed<PythonException>(testing::Property(
          &PythonException::ReadBacktrace,
          testing::AnyOf(
              testing::ContainsRegex("MyError: <exception str\\(\\) failed>"),
              testing::ContainsRegex("unprintable MyError")))));

#endif
}

TEST_F(PythonDataObjectsTest, TestRun) {

  PythonDictionary globals(PyInitialValue::Empty);

  auto x = As<long long>(runStringOneLine("40 + 2", globals, globals));
  ASSERT_THAT_EXPECTED(x, llvm::Succeeded());
  EXPECT_EQ(x.get(), 42l);

  Expected<PythonObject> r = runStringOneLine("n = 42", globals, globals);
  ASSERT_THAT_EXPECTED(r, llvm::Succeeded());
  auto y = As<long long>(globals.GetItem("n"));
  ASSERT_THAT_EXPECTED(y, llvm::Succeeded());
  EXPECT_EQ(y.get(), 42l);

  const char script[] = R"(
def foobar():
  return "foo" + "bar" + "baz"
g = foobar()
)";

  r = runStringMultiLine(script, globals, globals);
  ASSERT_THAT_EXPECTED(r, llvm::Succeeded());
  auto g = As<std::string>(globals.GetItem("g"));
  ASSERT_THAT_EXPECTED(g, llvm::HasValue("foobarbaz"));
}
