#pragma once

#include <string>

struct _typeobject {
    const char *tp_name = "standalone-python-shim";
};

struct _object {
    _typeobject *ob_type = nullptr;
};
typedef _object PyObject;

inline int PyCallable_Check(PyObject *) { return 0; }
inline int PyErr_ExceptionMatches(PyObject *) { return 0; }
inline void PyErr_Clear() {}
inline void PyErr_Print() {}
inline int PyUnicode_Check(PyObject *) { return 0; }
inline int PyLong_Check(PyObject *) { return 0; }
inline int PyFloat_Check(PyObject *) { return 0; }
inline PyObject *PyObject_Str(PyObject *) { return nullptr; }
inline void Py_XDECREF(PyObject *) {}
inline const char *PyUnicode_AsUTF8(PyObject *) { return ""; }

inline PyObject *PyExc_KeyError = nullptr;
inline PyObject *Py_None = nullptr;

namespace boost {
namespace python {

class error_already_set {};

class object {
public:
    object() = default;

    template <typename T>
    explicit object(const T &) {}

    template <typename T>
    object &operator=(const T &) { return *this; }

    object attr(const char *) const { return object(); }
    object operator[](const char *) const { return object(); }
    object operator[](const std::string &) const { return object(); }
    object operator[](int) const { return object(); }
    PyObject *ptr() const { return nullptr; }
};

class list : public object {
public:
    using object::object;
    list() = default;
    explicit list(const object &) {}

    template <typename T>
    void append(const T &) {}
};

class tuple : public object {
public:
    tuple() = default;
    explicit tuple(const list &) {}
};

class dict : public object {
public:
    object keys() const { return object(); }
};

class scope {
public:
    explicit scope(const object &) {}
    object attr(const char *) const { return object(); }
};

template <typename T>
object import(const T &) { return object(); }

template <typename T>
class extract {
public:
    explicit extract(const object &) {}

    operator T() const { return T(); }
};

inline int len(const object &) { return 0; }
inline void handle_exception() {}

}  // namespace python
}  // namespace boost
