//===-- PythonDataObjects.cpp ------------------------------------*- C++
//-*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifdef LLDB_DISABLE_PYTHON

// Python is disabled in this build

#else

#include "PythonDataObjects.h"
#include "ScriptInterpreterPython.h"

#include "lldb/Core/Stream.h"
#include "lldb/Host/File.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Interpreter/ScriptInterpreter.h"

#include "llvm/Support/ConvertUTF.h"

#include <stdio.h>

#include "llvm/ADT/StringSwitch.h"

using namespace lldb_private;
using namespace lldb;

void StructuredPythonObject::Dump(Stream &s, bool pretty_print) const {
  s << "Python Obj: 0x" << GetValue();
}

//----------------------------------------------------------------------
// PythonObject
//----------------------------------------------------------------------

void PythonObject::Dump(Stream &strm) const {
  if (m_py_obj) {
    FILE *file = ::tmpfile();
    if (file) {
      ::PyObject_Print(m_py_obj, file, 0);
      const long length = ftell(file);
      if (length) {
        ::rewind(file);
        std::vector<char> file_contents(length, '\0');
        const size_t length_read =
            ::fread(file_contents.data(), 1, file_contents.size(), file);
        if (length_read > 0)
          strm.Write(file_contents.data(), length_read);
      }
      ::fclose(file);
    }
  } else
    strm.PutCString("NULL");
}

PyObjectType PythonObject::GetObjectType() const {
  if (!IsAllocated())
    return PyObjectType::None;

  if (PythonModule::Check(m_py_obj))
    return PyObjectType::Module;
  if (PythonList::Check(m_py_obj))
    return PyObjectType::List;
  if (PythonTuple::Check(m_py_obj))
    return PyObjectType::Tuple;
  if (PythonDictionary::Check(m_py_obj))
    return PyObjectType::Dictionary;
  if (PythonString::Check(m_py_obj))
    return PyObjectType::String;
#if PY_MAJOR_VERSION >= 3
  if (PythonBytes::Check(m_py_obj))
    return PyObjectType::Bytes;
#endif
  if (PythonByteArray::Check(m_py_obj))
    return PyObjectType::ByteArray;
  if (PythonInteger::Check(m_py_obj))
    return PyObjectType::Integer;
  if (PythonFile::Check(m_py_obj))
    return PyObjectType::File;
  if (PythonCallable::Check(m_py_obj))
    return PyObjectType::Callable;
  return PyObjectType::Unknown;
}

PythonString PythonObject::Repr() const {
  if (!m_py_obj)
    return PythonString();
  PyObject *repr = PyObject_Repr(m_py_obj);
  if (!repr)
    return PythonString();
  return PythonString(PyRefType::Owned, repr);
}

PythonString PythonObject::Str() const {
  if (!m_py_obj)
    return PythonString();
  PyObject *str = PyObject_Str(m_py_obj);
  if (!str)
    return PythonString();
  return PythonString(PyRefType::Owned, str);
}

PythonObject
PythonObject::ResolveNameWithDictionary(llvm::StringRef name,
                                        const PythonDictionary &dict) {
  size_t dot_pos = name.find_first_of('.');
  llvm::StringRef piece = name.substr(0, dot_pos);
  PythonObject result = dict.GetItemForKey(PythonString(piece));
  if (dot_pos == llvm::StringRef::npos) {
    // There was no dot, we're done.
    return result;
  }

  // There was a dot.  The remaining portion of the name should be looked up in
  // the context of the object that was found in the dictionary.
  return result.ResolveName(name.substr(dot_pos + 1));
}

PythonObject PythonObject::ResolveName(llvm::StringRef name) const {
  // Resolve the name in the context of the specified object.  If,
  // for example, `this` refers to a PyModule, then this will look for
  // `name` in this module.  If `this` refers to a PyType, then it will
  // resolve `name` as an attribute of that type.  If `this` refers to
  // an instance of an object, then it will resolve `name` as the value
  // of the specified field.
  //
  // This function handles dotted names so that, for example, if `m_py_obj`
  // refers to the `sys` module, and `name` == "path.append", then it
  // will find the function `sys.path.append`.

  size_t dot_pos = name.find_first_of('.');
  if (dot_pos == llvm::StringRef::npos) {
    // No dots in the name, we should be able to find the value immediately
    // as an attribute of `m_py_obj`.
    return GetAttributeValue(name);
  }

  // Look up the first piece of the name, and resolve the rest as a child of
  // that.
  PythonObject parent = ResolveName(name.substr(0, dot_pos));
  if (!parent.IsAllocated())
    return PythonObject();

  // Tail recursion.. should be optimized by the compiler
  return parent.ResolveName(name.substr(dot_pos + 1));
}

bool PythonObject::HasAttribute(llvm::StringRef attr) const {
  if (!IsValid())
    return false;
  PythonString py_attr(attr);
  return !!PyObject_HasAttr(m_py_obj, py_attr.get());
}

PythonObject PythonObject::GetAttributeValue(llvm::StringRef attr) const {
  if (!IsValid())
    return PythonObject();

  PythonString py_attr(attr);
  if (!PyObject_HasAttr(m_py_obj, py_attr.get()))
    return PythonObject();

  return PythonObject(PyRefType::Owned,
                      PyObject_GetAttr(m_py_obj, py_attr.get()));
}

bool PythonObject::IsNone() const { return m_py_obj == Py_None; }

bool PythonObject::IsValid() const { return m_py_obj != nullptr; }

bool PythonObject::IsAllocated() const { return IsValid() && !IsNone(); }

StructuredData::ObjectSP PythonObject::CreateStructuredObject() const {
  switch (GetObjectType()) {
  case PyObjectType::Dictionary:
    return PythonDictionary(PyRefType::Borrowed, m_py_obj)
        .CreateStructuredDictionary();
  case PyObjectType::Integer:
    return PythonInteger(PyRefType::Borrowed, m_py_obj)
        .CreateStructuredInteger();
  case PyObjectType::List:
    return PythonList(PyRefType::Borrowed, m_py_obj).CreateStructuredArray();
  case PyObjectType::String:
    return PythonString(PyRefType::Borrowed, m_py_obj).CreateStructuredString();
  case PyObjectType::Bytes:
    return PythonBytes(PyRefType::Borrowed, m_py_obj).CreateStructuredString();
  case PyObjectType::ByteArray:
    return PythonByteArray(PyRefType::Borrowed, m_py_obj)
        .CreateStructuredString();
  case PyObjectType::None:
    return StructuredData::ObjectSP();
  default:
    return StructuredData::ObjectSP(new StructuredPythonObject(m_py_obj));
  }
}

//----------------------------------------------------------------------
// PythonString
//----------------------------------------------------------------------
PythonBytes::PythonBytes() : PythonObject() {}

PythonBytes::PythonBytes(llvm::ArrayRef<uint8_t> bytes) : PythonObject() {
  SetBytes(bytes);
}

PythonBytes::PythonBytes(const uint8_t *bytes, size_t length) : PythonObject() {
  SetBytes(llvm::ArrayRef<uint8_t>(bytes, length));
}

PythonBytes::PythonBytes(PyRefType type, PyObject *py_obj) : PythonObject() {
  Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a string
}

PythonBytes::PythonBytes(const PythonBytes &object) : PythonObject(object) {}

PythonBytes::~PythonBytes() {}

bool PythonBytes::Check(PyObject *py_obj) {
  if (!py_obj)
    return false;
  if (PyBytes_Check(py_obj))
    return true;
  return false;
}

void PythonBytes::Reset(PyRefType type, PyObject *py_obj) {
  // Grab the desired reference type so that if we end up rejecting
  // `py_obj` it still gets decremented if necessary.
  PythonObject result(type, py_obj);

  if (!PythonBytes::Check(py_obj)) {
    PythonObject::Reset();
    return;
  }

  // Calling PythonObject::Reset(const PythonObject&) will lead to stack
  // overflow since it calls
  // back into the virtual implementation.
  PythonObject::Reset(PyRefType::Borrowed, result.get());
}

llvm::ArrayRef<uint8_t> PythonBytes::GetBytes() const {
  if (!IsValid())
    return llvm::ArrayRef<uint8_t>();

  Py_ssize_t size;
  char *c;

  PyBytes_AsStringAndSize(m_py_obj, &c, &size);
  return llvm::ArrayRef<uint8_t>(reinterpret_cast<uint8_t *>(c), size);
}

size_t PythonBytes::GetSize() const {
  if (!IsValid())
    return 0;
  return PyBytes_Size(m_py_obj);
}

void PythonBytes::SetBytes(llvm::ArrayRef<uint8_t> bytes) {
  const char *data = reinterpret_cast<const char *>(bytes.data());
  PyObject *py_bytes = PyBytes_FromStringAndSize(data, bytes.size());
  PythonObject::Reset(PyRefType::Owned, py_bytes);
}

StructuredData::StringSP PythonBytes::CreateStructuredString() const {
  StructuredData::StringSP result(new StructuredData::String);
  Py_ssize_t size;
  char *c;
  PyBytes_AsStringAndSize(m_py_obj, &c, &size);
  result->SetValue(std::string(c, size));
  return result;
}

PythonByteArray::PythonByteArray(llvm::ArrayRef<uint8_t> bytes)
    : PythonByteArray(bytes.data(), bytes.size()) {}

PythonByteArray::PythonByteArray(const uint8_t *bytes, size_t length) {
  const char *str = reinterpret_cast<const char *>(bytes);
  Reset(PyRefType::Owned, PyByteArray_FromStringAndSize(str, length));
}

PythonByteArray::PythonByteArray(PyRefType type, PyObject *o) {
  Reset(type, o);
}

PythonByteArray::PythonByteArray(const PythonBytes &object)
    : PythonObject(object) {}

PythonByteArray::~PythonByteArray() {}

bool PythonByteArray::Check(PyObject *py_obj) {
  if (!py_obj)
    return false;
  if (PyByteArray_Check(py_obj))
    return true;
  return false;
}

void PythonByteArray::Reset(PyRefType type, PyObject *py_obj) {
  // Grab the desired reference type so that if we end up rejecting
  // `py_obj` it still gets decremented if necessary.
  PythonObject result(type, py_obj);

  if (!PythonByteArray::Check(py_obj)) {
    PythonObject::Reset();
    return;
  }

  // Calling PythonObject::Reset(const PythonObject&) will lead to stack
  // overflow since it calls
  // back into the virtual implementation.
  PythonObject::Reset(PyRefType::Borrowed, result.get());
}

llvm::ArrayRef<uint8_t> PythonByteArray::GetBytes() const {
  if (!IsValid())
    return llvm::ArrayRef<uint8_t>();

  char *c = PyByteArray_AsString(m_py_obj);
  size_t size = GetSize();
  return llvm::ArrayRef<uint8_t>(reinterpret_cast<uint8_t *>(c), size);
}

size_t PythonByteArray::GetSize() const {
  if (!IsValid())
    return 0;

  return PyByteArray_Size(m_py_obj);
}

StructuredData::StringSP PythonByteArray::CreateStructuredString() const {
  StructuredData::StringSP result(new StructuredData::String);
  llvm::ArrayRef<uint8_t> bytes = GetBytes();
  const char *str = reinterpret_cast<const char *>(bytes.data());
  result->SetValue(std::string(str, bytes.size()));
  return result;
}

//----------------------------------------------------------------------
// PythonString
//----------------------------------------------------------------------

PythonString::PythonString(PyRefType type, PyObject *py_obj) : PythonObject() {
  Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a string
}

PythonString::PythonString(const PythonString &object) : PythonObject(object) {}

PythonString::PythonString(llvm::StringRef string) : PythonObject() {
  SetString(string);
}

PythonString::PythonString(const char *string) : PythonObject() {
  SetString(llvm::StringRef(string));
}

PythonString::PythonString() : PythonObject() {}

PythonString::~PythonString() {}

bool PythonString::Check(PyObject *py_obj) {
  if (!py_obj)
    return false;

  if (PyUnicode_Check(py_obj))
    return true;
#if PY_MAJOR_VERSION < 3
  if (PyString_Check(py_obj))
    return true;
#endif
  return false;
}

void PythonString::Reset(PyRefType type, PyObject *py_obj) {
  // Grab the desired reference type so that if we end up rejecting
  // `py_obj` it still gets decremented if necessary.
  PythonObject result(type, py_obj);

  if (!PythonString::Check(py_obj)) {
    PythonObject::Reset();
    return;
  }
#if PY_MAJOR_VERSION < 3
  // In Python 2, Don't store PyUnicode objects directly, because we need
  // access to their underlying character buffers which Python 2 doesn't
  // provide.
  if (PyUnicode_Check(py_obj))
    result.Reset(PyRefType::Owned, PyUnicode_AsUTF8String(result.get()));
#endif
  // Calling PythonObject::Reset(const PythonObject&) will lead to stack
  // overflow since it calls
  // back into the virtual implementation.
  PythonObject::Reset(PyRefType::Borrowed, result.get());
}

llvm::StringRef PythonString::GetString() const {
  if (!IsValid())
    return llvm::StringRef();

  Py_ssize_t size;
  char *c;

#if PY_MAJOR_VERSION >= 3
  c = PyUnicode_AsUTF8AndSize(m_py_obj, &size);
#else
  PyString_AsStringAndSize(m_py_obj, &c, &size);
#endif
  return llvm::StringRef(c, size);
}

size_t PythonString::GetSize() const {
  if (IsValid()) {
#if PY_MAJOR_VERSION >= 3
    return PyUnicode_GetSize(m_py_obj);
#else
    return PyString_Size(m_py_obj);
#endif
  }
  return 0;
}

void PythonString::SetString(llvm::StringRef string) {
#if PY_MAJOR_VERSION >= 3
  PyObject *unicode = PyUnicode_FromStringAndSize(string.data(), string.size());
  PythonObject::Reset(PyRefType::Owned, unicode);
#else
  PyObject *str = PyString_FromStringAndSize(string.data(), string.size());
  PythonObject::Reset(PyRefType::Owned, str);
#endif
}

StructuredData::StringSP PythonString::CreateStructuredString() const {
  StructuredData::StringSP result(new StructuredData::String);
  result->SetValue(GetString());
  return result;
}

//----------------------------------------------------------------------
// PythonInteger
//----------------------------------------------------------------------

PythonInteger::PythonInteger() : PythonObject() {}

PythonInteger::PythonInteger(PyRefType type, PyObject *py_obj)
    : PythonObject() {
  Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a integer type
}

PythonInteger::PythonInteger(const PythonInteger &object)
    : PythonObject(object) {}

PythonInteger::PythonInteger(int64_t value) : PythonObject() {
  SetInteger(value);
}

PythonInteger::~PythonInteger() {}

bool PythonInteger::Check(PyObject *py_obj) {
  if (!py_obj)
    return false;

#if PY_MAJOR_VERSION >= 3
  // Python 3 does not have PyInt_Check.  There is only one type of
  // integral value, long.
  return PyLong_Check(py_obj);
#else
  return PyLong_Check(py_obj) || PyInt_Check(py_obj);
#endif
}

void PythonInteger::Reset(PyRefType type, PyObject *py_obj) {
  // Grab the desired reference type so that if we end up rejecting
  // `py_obj` it still gets decremented if necessary.
  PythonObject result(type, py_obj);

  if (!PythonInteger::Check(py_obj)) {
    PythonObject::Reset();
    return;
  }

#if PY_MAJOR_VERSION < 3
  // Always store this as a PyLong, which makes interoperability between
  // Python 2.x and Python 3.x easier.  This is only necessary in 2.x,
  // since 3.x doesn't even have a PyInt.
  if (PyInt_Check(py_obj)) {
    // Since we converted the original object to a different type, the new
    // object is an owned object regardless of the ownership semantics requested
    // by the user.
    result.Reset(PyRefType::Owned, PyLong_FromLongLong(PyInt_AsLong(py_obj)));
  }
#endif

  assert(PyLong_Check(result.get()) &&
         "Couldn't get a PyLong from this PyObject");

  // Calling PythonObject::Reset(const PythonObject&) will lead to stack
  // overflow since it calls
  // back into the virtual implementation.
  PythonObject::Reset(PyRefType::Borrowed, result.get());
}

int64_t PythonInteger::GetInteger() const {
  if (m_py_obj) {
    assert(PyLong_Check(m_py_obj) &&
           "PythonInteger::GetInteger has a PyObject that isn't a PyLong");

    int overflow = 0;
    int64_t result = PyLong_AsLongLongAndOverflow(m_py_obj, &overflow);
    if (overflow != 0) {
      // We got an integer that overflows, like 18446744072853913392L
      // we can't use PyLong_AsLongLong() as it will return
      // 0xffffffffffffffff. If we use the unsigned long long
      // it will work as expected.
      const uint64_t uval = PyLong_AsUnsignedLongLong(m_py_obj);
      result = static_cast<int64_t>(uval);
    }
    return result;
  }
  return UINT64_MAX;
}

void PythonInteger::SetInteger(int64_t value) {
  PythonObject::Reset(PyRefType::Owned, PyLong_FromLongLong(value));
}

StructuredData::IntegerSP PythonInteger::CreateStructuredInteger() const {
  StructuredData::IntegerSP result(new StructuredData::Integer);
  result->SetValue(GetInteger());
  return result;
}

//----------------------------------------------------------------------
// PythonList
//----------------------------------------------------------------------

PythonList::PythonList(PyInitialValue value) : PythonObject() {
  if (value == PyInitialValue::Empty)
    Reset(PyRefType::Owned, PyList_New(0));
}

PythonList::PythonList(int list_size) : PythonObject() {
  Reset(PyRefType::Owned, PyList_New(list_size));
}

PythonList::PythonList(PyRefType type, PyObject *py_obj) : PythonObject() {
  Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a list
}

PythonList::PythonList(const PythonList &list) : PythonObject(list) {}

PythonList::~PythonList() {}

bool PythonList::Check(PyObject *py_obj) {
  if (!py_obj)
    return false;
  return PyList_Check(py_obj);
}

void PythonList::Reset(PyRefType type, PyObject *py_obj) {
  // Grab the desired reference type so that if we end up rejecting
  // `py_obj` it still gets decremented if necessary.
  PythonObject result(type, py_obj);

  if (!PythonList::Check(py_obj)) {
    PythonObject::Reset();
    return;
  }

  // Calling PythonObject::Reset(const PythonObject&) will lead to stack
  // overflow since it calls
  // back into the virtual implementation.
  PythonObject::Reset(PyRefType::Borrowed, result.get());
}

uint32_t PythonList::GetSize() const {
  if (IsValid())
    return PyList_GET_SIZE(m_py_obj);
  return 0;
}

PythonObject PythonList::GetItemAtIndex(uint32_t index) const {
  if (IsValid())
    return PythonObject(PyRefType::Borrowed, PyList_GetItem(m_py_obj, index));
  return PythonObject();
}

void PythonList::SetItemAtIndex(uint32_t index, const PythonObject &object) {
  if (IsAllocated() && object.IsValid()) {
    // PyList_SetItem is documented to "steal" a reference, so we need to
    // convert it to an owned reference by incrementing it.
    Py_INCREF(object.get());
    PyList_SetItem(m_py_obj, index, object.get());
  }
}

void PythonList::AppendItem(const PythonObject &object) {
  if (IsAllocated() && object.IsValid()) {
    // `PyList_Append` does *not* steal a reference, so do not call `Py_INCREF`
    // here like we do with `PyList_SetItem`.
    PyList_Append(m_py_obj, object.get());
  }
}

StructuredData::ArraySP PythonList::CreateStructuredArray() const {
  StructuredData::ArraySP result(new StructuredData::Array);
  uint32_t count = GetSize();
  for (uint32_t i = 0; i < count; ++i) {
    PythonObject obj = GetItemAtIndex(i);
    result->AddItem(obj.CreateStructuredObject());
  }
  return result;
}

//----------------------------------------------------------------------
// PythonTuple
//----------------------------------------------------------------------

PythonTuple::PythonTuple(PyInitialValue value) : PythonObject() {
  if (value == PyInitialValue::Empty)
    Reset(PyRefType::Owned, PyTuple_New(0));
}

PythonTuple::PythonTuple(int tuple_size) : PythonObject() {
  Reset(PyRefType::Owned, PyTuple_New(tuple_size));
}

PythonTuple::PythonTuple(PyRefType type, PyObject *py_obj) : PythonObject() {
  Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a tuple
}

PythonTuple::PythonTuple(const PythonTuple &tuple) : PythonObject(tuple) {}

PythonTuple::PythonTuple(std::initializer_list<PythonObject> objects) {
  m_py_obj = PyTuple_New(objects.size());

  uint32_t idx = 0;
  for (auto object : objects) {
    if (object.IsValid())
      SetItemAtIndex(idx, object);
    idx++;
  }
}

PythonTuple::PythonTuple(std::initializer_list<PyObject *> objects) {
  m_py_obj = PyTuple_New(objects.size());

  uint32_t idx = 0;
  for (auto py_object : objects) {
    PythonObject object(PyRefType::Borrowed, py_object);
    if (object.IsValid())
      SetItemAtIndex(idx, object);
    idx++;
  }
}

PythonTuple::~PythonTuple() {}

bool PythonTuple::Check(PyObject *py_obj) {
  if (!py_obj)
    return false;
  return PyTuple_Check(py_obj);
}

void PythonTuple::Reset(PyRefType type, PyObject *py_obj) {
  // Grab the desired reference type so that if we end up rejecting
  // `py_obj` it still gets decremented if necessary.
  PythonObject result(type, py_obj);

  if (!PythonTuple::Check(py_obj)) {
    PythonObject::Reset();
    return;
  }

  // Calling PythonObject::Reset(const PythonObject&) will lead to stack
  // overflow since it calls
  // back into the virtual implementation.
  PythonObject::Reset(PyRefType::Borrowed, result.get());
}

uint32_t PythonTuple::GetSize() const {
  if (IsValid())
    return PyTuple_GET_SIZE(m_py_obj);
  return 0;
}

PythonObject PythonTuple::GetItemAtIndex(uint32_t index) const {
  if (IsValid())
    return PythonObject(PyRefType::Borrowed, PyTuple_GetItem(m_py_obj, index));
  return PythonObject();
}

void PythonTuple::SetItemAtIndex(uint32_t index, const PythonObject &object) {
  if (IsAllocated() && object.IsValid()) {
    // PyTuple_SetItem is documented to "steal" a reference, so we need to
    // convert it to an owned reference by incrementing it.
    Py_INCREF(object.get());
    PyTuple_SetItem(m_py_obj, index, object.get());
  }
}

StructuredData::ArraySP PythonTuple::CreateStructuredArray() const {
  StructuredData::ArraySP result(new StructuredData::Array);
  uint32_t count = GetSize();
  for (uint32_t i = 0; i < count; ++i) {
    PythonObject obj = GetItemAtIndex(i);
    result->AddItem(obj.CreateStructuredObject());
  }
  return result;
}

//----------------------------------------------------------------------
// PythonDictionary
//----------------------------------------------------------------------

PythonDictionary::PythonDictionary(PyInitialValue value) : PythonObject() {
  if (value == PyInitialValue::Empty)
    Reset(PyRefType::Owned, PyDict_New());
}

PythonDictionary::PythonDictionary(PyRefType type, PyObject *py_obj)
    : PythonObject() {
  Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a dictionary
}

PythonDictionary::PythonDictionary(const PythonDictionary &object)
    : PythonObject(object) {}

PythonDictionary::~PythonDictionary() {}

bool PythonDictionary::Check(PyObject *py_obj) {
  if (!py_obj)
    return false;

  return PyDict_Check(py_obj);
}

void PythonDictionary::Reset(PyRefType type, PyObject *py_obj) {
  // Grab the desired reference type so that if we end up rejecting
  // `py_obj` it still gets decremented if necessary.
  PythonObject result(type, py_obj);

  if (!PythonDictionary::Check(py_obj)) {
    PythonObject::Reset();
    return;
  }

  // Calling PythonObject::Reset(const PythonObject&) will lead to stack
  // overflow since it calls
  // back into the virtual implementation.
  PythonObject::Reset(PyRefType::Borrowed, result.get());
}

uint32_t PythonDictionary::GetSize() const {
  if (IsValid())
    return PyDict_Size(m_py_obj);
  return 0;
}

PythonList PythonDictionary::GetKeys() const {
  if (IsValid())
    return PythonList(PyRefType::Owned, PyDict_Keys(m_py_obj));
  return PythonList(PyInitialValue::Invalid);
}

PythonObject PythonDictionary::GetItemForKey(const PythonObject &key) const {
  if (IsAllocated() && key.IsValid())
    return PythonObject(PyRefType::Borrowed,
                        PyDict_GetItem(m_py_obj, key.get()));
  return PythonObject();
}

void PythonDictionary::SetItemForKey(const PythonObject &key,
                                     const PythonObject &value) {
  if (IsAllocated() && key.IsValid() && value.IsValid())
    PyDict_SetItem(m_py_obj, key.get(), value.get());
}

StructuredData::DictionarySP
PythonDictionary::CreateStructuredDictionary() const {
  StructuredData::DictionarySP result(new StructuredData::Dictionary);
  PythonList keys(GetKeys());
  uint32_t num_keys = keys.GetSize();
  for (uint32_t i = 0; i < num_keys; ++i) {
    PythonObject key = keys.GetItemAtIndex(i);
    PythonObject value = GetItemForKey(key);
    StructuredData::ObjectSP structured_value = value.CreateStructuredObject();
    result->AddItem(key.Str().GetString(), structured_value);
  }
  return result;
}

PythonModule::PythonModule() : PythonObject() {}

PythonModule::PythonModule(PyRefType type, PyObject *py_obj) {
  Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a module
}

PythonModule::PythonModule(const PythonModule &dict) : PythonObject(dict) {}

PythonModule::~PythonModule() {}

PythonModule PythonModule::BuiltinsModule() {
#if PY_MAJOR_VERSION >= 3
  return AddModule("builtins");
#else
  return AddModule("__builtin__");
#endif
}

PythonModule PythonModule::MainModule() { return AddModule("__main__"); }

PythonModule PythonModule::AddModule(llvm::StringRef module) {
  std::string str = module.str();
  return PythonModule(PyRefType::Borrowed, PyImport_AddModule(str.c_str()));
}

PythonModule PythonModule::ImportModule(llvm::StringRef module) {
  std::string str = module.str();
  return PythonModule(PyRefType::Owned, PyImport_ImportModule(str.c_str()));
}

bool PythonModule::Check(PyObject *py_obj) {
  if (!py_obj)
    return false;

  return PyModule_Check(py_obj);
}

void PythonModule::Reset(PyRefType type, PyObject *py_obj) {
  // Grab the desired reference type so that if we end up rejecting
  // `py_obj` it still gets decremented if necessary.
  PythonObject result(type, py_obj);

  if (!PythonModule::Check(py_obj)) {
    PythonObject::Reset();
    return;
  }

  // Calling PythonObject::Reset(const PythonObject&) will lead to stack
  // overflow since it calls
  // back into the virtual implementation.
  PythonObject::Reset(PyRefType::Borrowed, result.get());
}

PythonDictionary PythonModule::GetDictionary() const {
  return PythonDictionary(PyRefType::Borrowed, PyModule_GetDict(m_py_obj));
}

PythonCallable::PythonCallable() : PythonObject() {}

PythonCallable::PythonCallable(PyRefType type, PyObject *py_obj) {
  Reset(type, py_obj); // Use "Reset()" to ensure that py_obj is a callable
}

PythonCallable::PythonCallable(const PythonCallable &callable)
    : PythonObject(callable) {}

PythonCallable::~PythonCallable() {}

bool PythonCallable::Check(PyObject *py_obj) {
  if (!py_obj)
    return false;

  return PyCallable_Check(py_obj);
}

void PythonCallable::Reset(PyRefType type, PyObject *py_obj) {
  // Grab the desired reference type so that if we end up rejecting
  // `py_obj` it still gets decremented if necessary.
  PythonObject result(type, py_obj);

  if (!PythonCallable::Check(py_obj)) {
    PythonObject::Reset();
    return;
  }

  // Calling PythonObject::Reset(const PythonObject&) will lead to stack
  // overflow since it calls
  // back into the virtual implementation.
  PythonObject::Reset(PyRefType::Borrowed, result.get());
}

PythonCallable::ArgInfo PythonCallable::GetNumArguments() const {
  ArgInfo result = {0, false, false, false};
  if (!IsValid())
    return result;

  PyObject *py_func_obj = m_py_obj;
  if (PyMethod_Check(py_func_obj)) {
    py_func_obj = PyMethod_GET_FUNCTION(py_func_obj);
    PythonObject im_self = GetAttributeValue("im_self");
    if (im_self.IsValid() && !im_self.IsNone())
      result.is_bound_method = true;
  } else {
    // see if this is a callable object with an __call__ method
    if (!PyFunction_Check(py_func_obj)) {
      PythonObject __call__ = GetAttributeValue("__call__");
      if (__call__.IsValid()) {
        auto __callable__ = __call__.AsType<PythonCallable>();
        if (__callable__.IsValid()) {
          py_func_obj = PyMethod_GET_FUNCTION(__callable__.get());
          PythonObject im_self = GetAttributeValue("im_self");
          if (im_self.IsValid() && !im_self.IsNone())
            result.is_bound_method = true;
        }
      }
    }
  }

  if (!py_func_obj)
    return result;

  PyCodeObject *code = (PyCodeObject *)PyFunction_GET_CODE(py_func_obj);
  if (!code)
    return result;

  result.count = code->co_argcount;
  result.has_varargs = !!(code->co_flags & CO_VARARGS);
  result.has_kwargs = !!(code->co_flags & CO_VARKEYWORDS);
  return result;
}

PythonObject PythonCallable::operator()() {
  return PythonObject(PyRefType::Owned, PyObject_CallObject(m_py_obj, nullptr));
}

PythonObject PythonCallable::
operator()(std::initializer_list<PyObject *> args) {
  PythonTuple arg_tuple(args);
  return PythonObject(PyRefType::Owned,
                      PyObject_CallObject(m_py_obj, arg_tuple.get()));
}

PythonObject PythonCallable::
operator()(std::initializer_list<PythonObject> args) {
  PythonTuple arg_tuple(args);
  return PythonObject(PyRefType::Owned,
                      PyObject_CallObject(m_py_obj, arg_tuple.get()));
}

PythonFile::PythonFile() : PythonObject() {}

PythonFile::PythonFile(File &file, const char *mode) { Reset(file, mode); }

PythonFile::PythonFile(const char *path, const char *mode) {
  lldb_private::File file(path, GetOptionsFromMode(mode));
  Reset(file, mode);
}

PythonFile::PythonFile(PyRefType type, PyObject *o) { Reset(type, o); }

PythonFile::~PythonFile() {}

bool PythonFile::Check(PyObject *py_obj) {
#if PY_MAJOR_VERSION < 3
  return PyFile_Check(py_obj);
#else
  // In Python 3, there is no `PyFile_Check`, and in fact PyFile is not even a
  // first-class object type anymore.  `PyFile_FromFd` is just a thin wrapper
  // over `io.open()`, which returns some object derived from `io.IOBase`.
  // As a result, the only way to detect a file in Python 3 is to check whether
  // it inherits from `io.IOBase`.  Since it is possible for non-files to also
  // inherit from `io.IOBase`, we additionally verify that it has the `fileno`
  // attribute, which should guarantee that it is backed by the file system.
  PythonObject io_module(PyRefType::Owned, PyImport_ImportModule("io"));
  PythonDictionary io_dict(PyRefType::Borrowed,
                           PyModule_GetDict(io_module.get()));
  PythonObject io_base_class = io_dict.GetItemForKey(PythonString("IOBase"));

  PythonObject object_type(PyRefType::Owned, PyObject_Type(py_obj));

  if (1 != PyObject_IsSubclass(object_type.get(), io_base_class.get()))
    return false;
  if (!object_type.HasAttribute("fileno"))
    return false;

  return true;
#endif
}

void PythonFile::Reset(PyRefType type, PyObject *py_obj) {
  // Grab the desired reference type so that if we end up rejecting
  // `py_obj` it still gets decremented if necessary.
  PythonObject result(type, py_obj);

  if (!PythonFile::Check(py_obj)) {
    PythonObject::Reset();
    return;
  }

  // Calling PythonObject::Reset(const PythonObject&) will lead to stack
  // overflow since it calls back into the virtual implementation.
  PythonObject::Reset(PyRefType::Borrowed, result.get());
}

void PythonFile::Reset(File &file, const char *mode) {
  if (!file.IsValid()) {
    Reset();
    return;
  }

  char *cmode = const_cast<char *>(mode);
#if PY_MAJOR_VERSION >= 3
  Reset(PyRefType::Owned, PyFile_FromFd(file.GetDescriptor(), nullptr, cmode,
                                        -1, nullptr, "ignore", nullptr, 0));
#else
  // Read through the Python source, doesn't seem to modify these strings
  Reset(PyRefType::Owned,
        PyFile_FromFile(file.GetStream(), const_cast<char *>(""), cmode,
                        nullptr));
#endif
}

uint32_t PythonFile::GetOptionsFromMode(llvm::StringRef mode) {
  if (mode.empty())
    return 0;

  return llvm::StringSwitch<uint32_t>(mode.str())
      .Case("r", File::eOpenOptionRead)
      .Case("w", File::eOpenOptionWrite)
      .Case("a", File::eOpenOptionWrite | File::eOpenOptionAppend |
                     File::eOpenOptionCanCreate)
      .Case("r+", File::eOpenOptionRead | File::eOpenOptionWrite)
      .Case("w+", File::eOpenOptionRead | File::eOpenOptionWrite |
                      File::eOpenOptionCanCreate | File::eOpenOptionTruncate)
      .Case("a+", File::eOpenOptionRead | File::eOpenOptionWrite |
                      File::eOpenOptionAppend | File::eOpenOptionCanCreate)
      .Default(0);
}

bool PythonFile::GetUnderlyingFile(File &file) const {
  if (!IsValid())
    return false;

  file.Close();
  // We don't own the file descriptor returned by this function, make sure the
  // File object knows about that.
  file.SetDescriptor(PyObject_AsFileDescriptor(m_py_obj), false);
  PythonString py_mode = GetAttributeValue("mode").AsType<PythonString>();
  file.SetOptions(PythonFile::GetOptionsFromMode(py_mode.GetString()));
  return file.IsValid();
}

#endif
