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

#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H
#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H

#ifndef LLDB_DISABLE_PYTHON

// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/lldb-defines.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Core/StructuredData.h"
#include "lldb/Core/Flags.h"
#include "lldb/Host/File.h"
#include "lldb/Interpreter/OptionValue.h"

#include "llvm/ADT/ArrayRef.h"

namespace lldb_private {

class PythonBytes;
class PythonString;
class PythonList;
class PythonDictionary;
class PythonInteger;

class StructuredPythonObject : public StructuredData::Generic
{
public:
    StructuredPythonObject()
        : StructuredData::Generic()
    {
    }

    StructuredPythonObject(void *obj)
        : StructuredData::Generic(obj)
    {
        Py_XINCREF(GetValue());
    }

    ~StructuredPythonObject() override
    {
        if (Py_IsInitialized())
            Py_XDECREF(GetValue());
        SetValue(nullptr);
    }

    bool
    IsValid() const override
    {
        return GetValue() && GetValue() != Py_None;
    }

    void Dump(Stream &s) const override;

private:
    DISALLOW_COPY_AND_ASSIGN(StructuredPythonObject);
};

enum class PyObjectType
{
    Unknown,
    None,
    Integer,
    Dictionary,
    List,
    String,
    Bytes,
    Module,
    Callable,
    Tuple,
    File
};

enum class PyRefType
{
    Borrowed, // We are not given ownership of the incoming PyObject.
              // We cannot safely hold it without calling Py_INCREF.
    Owned     // We have ownership of the incoming PyObject.  We should
              // not call Py_INCREF.
};

enum class PyInitialValue
{
    Invalid,
    Empty
};

class PythonObject
{
public:
    PythonObject()
        : m_py_obj(nullptr)
    {
    }

    PythonObject(PyRefType type, PyObject *py_obj)
        : m_py_obj(nullptr)
    {
        Reset(type, py_obj);
    }

    PythonObject(const PythonObject &rhs)
        : m_py_obj(nullptr)
    {
        Reset(rhs);
    }

    virtual ~PythonObject()
    {
        Reset();
    }

    void
    Reset()
    {
        // Avoid calling the virtual method since it's not necessary
        // to actually validate the type of the PyObject if we're
        // just setting to null.
        if (Py_IsInitialized())
            Py_XDECREF(m_py_obj);
        m_py_obj = nullptr;
    }

    void
    Reset(const PythonObject &rhs)
    {
        // Avoid calling the virtual method if it's not necessary
        // to actually validate the type of the PyObject.
        if (!rhs.IsValid())
            Reset();
        else
            Reset(PyRefType::Borrowed, rhs.m_py_obj);
    }

    // PythonObject is implicitly convertible to PyObject *, which will call the
    // wrong overload.  We want to explicitly disallow this, since a PyObject
    // *always* owns its reference.  Therefore the overload which takes a
    // PyRefType doesn't make sense, and the copy constructor should be used.
    void
    Reset(PyRefType type, const PythonObject &ref) = delete;

    virtual void
    Reset(PyRefType type, PyObject *py_obj)
    {
        if (py_obj == m_py_obj)
            return;

        if (Py_IsInitialized())
            Py_XDECREF(m_py_obj);

        m_py_obj = py_obj;

        // If this is a borrowed reference, we need to convert it to
        // an owned reference by incrementing it.  If it is an owned
        // reference (for example the caller allocated it with PyDict_New()
        // then we must *not* increment it.
        if (Py_IsInitialized() && type == PyRefType::Borrowed)
            Py_XINCREF(m_py_obj);
    }
        
    void
    Dump () const
    {
        if (m_py_obj)
            _PyObject_Dump (m_py_obj);
        else
            puts ("NULL");
    }
        
    void
    Dump (Stream &strm) const;

    PyObject*
    get() const
    {
        return m_py_obj;
    }

    PyObject*
    release()
    {
        PyObject *result = m_py_obj;
        m_py_obj = nullptr;
        return result;
    }

    PythonObject &
    operator=(const PythonObject &other)
    {
        Reset(PyRefType::Borrowed, other.get());
        return *this;
    }

    PyObjectType
    GetObjectType() const;

    PythonString
    Repr() const;

    PythonString
    Str() const;

    static PythonObject
    ResolveNameWithDictionary(llvm::StringRef name, const PythonDictionary &dict);

    template<typename T>
    static T
    ResolveNameWithDictionary(llvm::StringRef name, const PythonDictionary &dict)
    {
        return ResolveNameWithDictionary(name, dict).AsType<T>();
    }

    PythonObject
    ResolveName(llvm::StringRef name) const;

    template<typename T>
    T
    ResolveName(llvm::StringRef name) const
    {
        return ResolveName(name).AsType<T>();
    }

    bool
    HasAttribute(llvm::StringRef attribute) const;

    PythonObject
    GetAttributeValue(llvm::StringRef attribute) const;

    bool
    IsValid() const;

    bool
    IsAllocated() const;

    bool
    IsNone() const;

    template<typename T>
    T AsType() const
    {
        if (!T::Check(m_py_obj))
            return T();
        return T(PyRefType::Borrowed, m_py_obj);
    }

    StructuredData::ObjectSP
    CreateStructuredObject() const;

protected:
    PyObject* m_py_obj;
};

class PythonBytes : public PythonObject
{
public:
    PythonBytes();
    explicit PythonBytes(llvm::ArrayRef<uint8_t> bytes);
    PythonBytes(const uint8_t *bytes, size_t length);
    PythonBytes(PyRefType type, PyObject *o);
    PythonBytes(const PythonBytes &object);

    ~PythonBytes() override;

    static bool
    Check(PyObject *py_obj);

    // Bring in the no-argument base class version
    using PythonObject::Reset;

    void
    Reset(PyRefType type, PyObject *py_obj) override;

    llvm::ArrayRef<uint8_t>
    GetBytes() const;

    size_t
    GetSize() const;

    void
    SetBytes(llvm::ArrayRef<uint8_t> stringbytes);

    StructuredData::StringSP
    CreateStructuredString() const;
};

class PythonString : public PythonObject
{
public:
    PythonString();
    explicit PythonString(llvm::StringRef string);
    explicit PythonString(const char *string);
    PythonString(PyRefType type, PyObject *o);
    PythonString(const PythonString &object);

    ~PythonString() override;

    static bool Check(PyObject *py_obj);

    // Bring in the no-argument base class version
    using PythonObject::Reset;

    void Reset(PyRefType type, PyObject *py_obj) override;

    llvm::StringRef
    GetString() const;

    size_t
    GetSize() const;

    void SetString(llvm::StringRef string);

    StructuredData::StringSP CreateStructuredString() const;
};

class PythonInteger : public PythonObject
{
public:
    PythonInteger();
    explicit PythonInteger(int64_t value);
    PythonInteger(PyRefType type, PyObject *o);
    PythonInteger(const PythonInteger &object);

    ~PythonInteger() override;

    static bool Check(PyObject *py_obj);

    // Bring in the no-argument base class version
    using PythonObject::Reset;

    void Reset(PyRefType type, PyObject *py_obj) override;

    int64_t GetInteger() const;

    void
    SetInteger (int64_t value);

    StructuredData::IntegerSP CreateStructuredInteger() const;
};

class PythonList : public PythonObject
{
public:
    PythonList() {}
    explicit PythonList(PyInitialValue value);
    explicit PythonList(int list_size);
    PythonList(PyRefType type, PyObject *o);
    PythonList(const PythonList &list);

    ~PythonList() override;

    static bool Check(PyObject *py_obj);

    // Bring in the no-argument base class version
    using PythonObject::Reset;

    void Reset(PyRefType type, PyObject *py_obj) override;

    uint32_t GetSize() const;

    PythonObject GetItemAtIndex(uint32_t index) const;

    void SetItemAtIndex(uint32_t index, const PythonObject &object);

    void AppendItem(const PythonObject &object);

    StructuredData::ArraySP CreateStructuredArray() const;
};

class PythonTuple : public PythonObject
{
public:
    PythonTuple() {}
    explicit PythonTuple(PyInitialValue value);
    explicit PythonTuple(int tuple_size);
    PythonTuple(PyRefType type, PyObject *o);
    PythonTuple(const PythonTuple &tuple);
    PythonTuple(std::initializer_list<PythonObject> objects);
    PythonTuple(std::initializer_list<PyObject*> objects);

    ~PythonTuple() override;

    static bool Check(PyObject *py_obj);

    // Bring in the no-argument base class version
    using PythonObject::Reset;

    void Reset(PyRefType type, PyObject *py_obj) override;

    uint32_t GetSize() const;

    PythonObject GetItemAtIndex(uint32_t index) const;

    void SetItemAtIndex(uint32_t index, const PythonObject &object);

    StructuredData::ArraySP CreateStructuredArray() const;
};

class PythonDictionary : public PythonObject
{
public:
    PythonDictionary() {}
    explicit PythonDictionary(PyInitialValue value);
    PythonDictionary(PyRefType type, PyObject *o);
    PythonDictionary(const PythonDictionary &dict);

    ~PythonDictionary() override;

    static bool Check(PyObject *py_obj);

    // Bring in the no-argument base class version
    using PythonObject::Reset;

    void Reset(PyRefType type, PyObject *py_obj) override;

    uint32_t GetSize() const;

    PythonList GetKeys() const;

    PythonObject GetItemForKey(const PythonObject &key) const;
    void SetItemForKey(const PythonObject &key, const PythonObject &value);

    StructuredData::DictionarySP CreateStructuredDictionary() const;
};

class PythonModule : public PythonObject
{
  public:
    PythonModule();
    PythonModule(PyRefType type, PyObject *o);
    PythonModule(const PythonModule &dict);

    ~PythonModule() override;

    static bool Check(PyObject *py_obj);

    static PythonModule
    BuiltinsModule();

    static PythonModule
    MainModule();

    static PythonModule
    AddModule(llvm::StringRef module);

    static PythonModule
    ImportModule(llvm::StringRef module);

    // Bring in the no-argument base class version
    using PythonObject::Reset;

    void Reset(PyRefType type, PyObject *py_obj) override;

    PythonDictionary GetDictionary() const;
};

class PythonCallable : public PythonObject
{
public:
    struct ArgInfo {
        size_t count;
        bool has_varargs : 1;
        bool has_kwargs : 1;
    };

    PythonCallable();
    PythonCallable(PyRefType type, PyObject *o);
    PythonCallable(const PythonCallable &dict);

    ~PythonCallable() override;

    static bool
    Check(PyObject *py_obj);

    // Bring in the no-argument base class version
    using PythonObject::Reset;

    void
    Reset(PyRefType type, PyObject *py_obj) override;

    ArgInfo
    GetNumArguments() const;

    PythonObject
    operator ()();

    PythonObject
    operator ()(std::initializer_list<PyObject*> args);

    PythonObject
    operator ()(std::initializer_list<PythonObject> args);

    template<typename Arg, typename... Args>
    PythonObject
    operator ()(const Arg &arg, Args... args)
    {
        return operator()({ arg, args... });
    }
};


class PythonFile : public PythonObject
{
  public:
    PythonFile();
    PythonFile(File &file, const char *mode);
    PythonFile(const char *path, const char *mode);
    PythonFile(PyRefType type, PyObject *o);

    ~PythonFile() override;

    static bool Check(PyObject *py_obj);

    using PythonObject::Reset;

    void Reset(PyRefType type, PyObject *py_obj) override;
    void Reset(File &file, const char *mode);

    static uint32_t GetOptionsFromMode(llvm::StringRef mode);
    
    bool GetUnderlyingFile(File &file) const;
};

} // namespace lldb_private

#endif

#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H
