/* ebdemo.c - embed python demo */

#include <stdio.h>
#include "Python.h"

extern void initsysinfoc();
PyObject *
NoExit(PyObject *a, PyObject *args)
        /* disallow all exiting */
{
        PyObject *mainModule, *mainDict;

        mainModule = PyImport_ImportModule("__main__");
        if(NULL != mainModule) {
                PyObject *mainDict;

                mainDict = PyModule_GetDict(mainModule);
                if(NULL != mainDict) {
                        PyObject *func  = 
                                  PyDict_GetItemString(mainDict,"ExitFunction");
                        if(NULL != func) {
                                PyObject *res = PyObject_CallFunction(func,
                                        "s","NoExit was called");
                                Py_DECREF(mainModule);
                                return res;
                        }
                }
                Py_DECREF(mainModule);
        }

        PyErr_SetString(PyExc_RuntimeError,"No exit allowed");
        return NULL;
}

static PyMethodDef hostModuleMethods[] = {
        { "NoExit", NoExit, METH_VARARGS },
        { NULL, NULL}
};

void
SetupHostModule(void)
{
        PyObject *hostmod, *sysmod;

        hostmod = Py_InitModule("hostModule",hostModuleMethods);
        sysmod = PyImport_ImportModule("sys");
        if(NULL != sysmod) {
                PyObject *sysDict, *noExitObj, *hostDict;
                sysDict = PyModule_GetDict(sysmod);
                hostDict = PyModule_GetDict(hostmod);
                if(NULL != sysDict && NULL != hostDict) {
                        noExitObj = PyDict_GetItemString(hostDict,"NoExit");
                        if(NULL != noExitObj)
                                PyDict_SetItemString(sysDict,"exit",noExitObj);
                }
                Py_DECREF(sysmod);
        }
}


int main(int argc, char **argv)
{
        int rc; 

         Py_SetProgramName(argv[0]);
        Py_Initialize();
        PySys_SetArgv(argc, argv);

        initsysinfoc();
        SetupHostModule();
		if(argc < 2)  {
                PySys_SetArgv(argc, argv);
                rc = PyRun_AnyFile(stdin,"???");
        } else {
                PySys_SetArgv(argc-1, argv+1);
                sprintf(cmd,"execfile('%s')",argv[1]);
                rc = PyRun_SimpleString(cmd);
              if(argc > 3)    /* argv[2] == class, argv[3] == method */
                      CallMethodInInstance(argv[2],argv[3]);
        }
        printf("Result Code is %d\n",rc);
        Py_Finalize();
        return rc;
}

void
CallMethodInInstance(char *klassname, char *method)
{
        PyObject *mainModule, *mainDict, *klassobj, *args, *instance;

        mainModule = PyImport_ImportModule("__main__");
        if(NULL == mainModule)
                return;

        mainDict = PyModule_GetDict(mainModule);
        Py_DECREF(mainModule);
        if(NULL == mainDict)
                return;

        klassobj = PyDict_GetItemString(mainDict,klassname);
        if(NULL == klassobj) {
                printf("Could not find class named %s in __main__\n",klassname);
                return;
        }
        args = Py_BuildValue("()");     /* create empty tuple for args */
        if(NULL == args)
                return;

        instance = PyInstance_New(klassobj,args,NULL);
        if(NULL == instance) {
                printf("Could not create instance of %s\n",klassname);
                return;
        }

        PyObject_CallMethod(instance, method, "s", "Call From CMII");
        Py_DECREF(instance);
}
