//  ************************************************************************************************
//
//  BornAgain: simulate and fit reflection and scattering
//
//! @file      PyCore/Embed/PyObjectPtr.h
//! @brief     Implements class PyObjectPtr
//!
//! @homepage  http://www.bornagainproject.org
//! @license   GNU General Public License v3 or higher (see COPYING)
//! @copyright Forschungszentrum Jülich GmbH 2018
//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
//
//  ************************************************************************************************

#include "PyObjectPtr.h"
#include "PyInterpreter.h"

#include <stdexcept> // runtime_error

PyObjectPtr::PyObjectPtr(PyObject* pyobject_ptr)
    : m_ptr{pyobject_ptr}
{
}

PyObjectPtr::~PyObjectPtr()
{
    discard();
}

PyObjectPtr::PyObjectPtr(PyObjectPtr&& other)
    : PyObjectPtr(other.release())
{
}

PyObject* PyObjectPtr::get()
{
    return m_ptr;
}

PyObject* PyObjectPtr::release()
{
    PyObject* pyobject_ptr{m_ptr};
    reset();
    return pyobject_ptr;
}

void PyObjectPtr::reset()
{
    m_ptr = nullptr;
}

void PyObjectPtr::discard()
{
    if (!PyInterpreter::isInitialized())
        throw(std::runtime_error("Decrementing Python reference-count without "
                                 "Python initialized leads to memory access violation "
                                 "(segmentation fault)"));

    PyInterpreter::DecRef(m_ptr);
    reset();
}

bool PyObjectPtr::valid() const
{
    return static_cast<bool>(m_ptr);
}