//===-- 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 "lldb-python.h"
#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) 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");

        return PyLong_AsLongLong(m_py_obj);
    }
    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().c_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
