// This file is part of the Coral project.
// Please read the copyright notice in the LICENSE file.

#include <coral/core/PyOperation.h>
#include <Python.h>
#include <coral/lib/assert.h>

/* uh... defined in coral/kernel_wrap.cxx */
PyObject* getElementPyObject(const coral::Element* ptr);

namespace coral {

	PyOperation::PyOperation(PyObject* _function,
				 const std::string& _language,
				 const std::string& _code,
				 bool _isWFR) : ref_counted(), function(_function), is_a_wfr(_isWFR),
						language(_language), code(_code) {
		coral_assert(PyFunction_Check(_function));
		Py_INCREF(this->function);
	}

	PyOperation::~PyOperation() throw () {
		Py_DECREF(this->function);
	}

	const std::string& PyOperation::getCode() const throw () {
		return code;
	}

	std::string PyOperation::getFuncName() const throw () {
		PyFunctionObject* f =
			reinterpret_cast<PyFunctionObject*>(this->function);
		return std::string(PyString_AsString(f->func_name));
	}

	PyObject* PyOperation::__call__(Element* self) {
		PyObject* ret = Py_None;
		PyObject* args = PyTuple_New(1);
		if (args) {
			PyObject* selfpy = getElementPyObject(self);
			if (selfpy) {
				PyTuple_SET_ITEM(args, 0, selfpy);
				ret =
					PyObject_Call(this->function, args, NULL);
			}
			Py_DECREF(args);
		}
		Py_XINCREF(ret);
		return ret;
	}
	PyObject* PyOperation::getFunc() const throw () {
		Py_INCREF(this->function);
		return this->function;
	}
}
