/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

#include <Python.h>
#include "uima/api.hpp"

// for u_init
#include "unicode/uclean.h"

#define MODULENAME "Pythonnator"

#ifdef LINUX
// Beacuse of UIMA not using the RTLD_GLOBAL flag when binding to this
// .so file, we do not get the exports from the dependent libraries in 
// when loading.  This flag causes the python .so file to be re-bound
// hopefully this can be removed pending a future relesase of UIMA
#define REBIND_PYTHON_SO 
#include <dlfcn.h>
#endif

using namespace uima;
using namespace std;
using namespace icu;

// copied from SwigGenerated code

// this function requires the SWIG code to be compiled with
// SWIGRUNTIME defined to be "", otherwise this function is static
// and does not scope outside of the library
#if !defined(SWIG_GLOBAL) && !defined(SWIGRUNTIME)
// SWIG 1.3.29 or better
#include "uimapywrap.h" 
#endif

const unsigned int FUNCTIONCOUNT=7;
enum { FUNCTION_INITIALIZE, FUNCTION_TYPESYSTEMINIT,
  FUNCTION_DESTROY, FUNCTION_RECONFIGURE, FUNCTION_PROCESS,
  FUNCTION_BATCHPROCESSCOMPLETE, FUNCTION_COLLECTIONPROCESSCOMPLETE };
static const char *function_name[FUNCTIONCOUNT] = {
  "initialize", "typeSystemInit", "destroy", "reconfigure", "process",
  "batchProcessComplete", "collectionProcessComplete"
};

class Pythonnator : public Annotator {
  PyThreadState *thread_state;
  PyObject *function[FUNCTIONCOUNT];
  int debug;
  swig_type_info *cas_type, *rs_type, *ts_type;
#ifdef REBIND_PYTHON_SO
      static void *library;
#endif
  static unsigned int refcount;

public:
  // We construct a python interpreter in initialize - it lives for the
  // life of the annotator - even if reconfigure happens.  Reconfigure
  // and intialize both set dirty so the source code in the source file
  // and contained in the type system are evaluated.

  TyErrorId initialize(AnnotatorContext &ac) {
	//    PyObject *main_module, *user_module;
    PyObject *user_module;
    PyObject *dict;
    swig_type_info *ac_type;
#ifdef PATH_MAX
    char srcfile[PATH_MAX + 256];
#else
    char srcfile[1000 + 256];
#endif

    for (unsigned int i=0; i<FUNCTIONCOUNT; i++) {
      function[i] = 0;
    } 

    debug = 0;
    if (ac.isParameterDefined("DebugLevel")) {
      ac.extractValue("DebugLevel", debug);
    }
    if (debug > 100) {
      cerr<< MODULENAME ": Initialize - debug=" << debug <<endl;
    }
    if (!ac.isParameterDefined("SourceFile")) {
      cerr<< MODULENAME ": Missing Python SourceFile" <<endl;
      return UIMA_ERR_USER_ANNOTATOR_COULD_NOT_INIT;
    }

    UnicodeString fn;
    ac.extractValue(UnicodeString("SourceFile"), fn);
    if (fn == "") {
      cerr<< MODULENAME ": Empty Python SourceFile" <<endl;
      return UIMA_ERR_USER_ANNOTATOR_COULD_NOT_INIT;
    }

    UErrorCode err = U_ZERO_ERROR;
    fn.extract(srcfile,sizeof(srcfile),0,err);
    if (U_FAILURE(err)) {
      cerr << MODULENAME ": Unable to extract parameter, got " << u_errorName(err) << endl;
      return UIMA_ERR_USER_ANNOTATOR_COULD_NOT_INIT;
    }

#ifdef REBIND_PYTHON_SO
      if (refcount == 0) 
        library = dlopen(PYTHONLIBRARYNAME , RTLD_LAZY | RTLD_GLOBAL);
      if (library == 0) {
        cerr<< MODULENAME ": unable to bind to python library " << 
          PYTHONLIBRARYNAME <<endl;
        cerr<< MODULENAME ": dlerror reports " << dlerror() << endl;
        return UIMA_ERR_USER_ANNOTATOR_COULD_NOT_INIT;
      } 
#endif
      if (refcount++ == 0) {
        // This is done here because older versions of UIMA cannot be counted on to properly
	// initialize ICU, and this is necessary for thread safety
        UErrorCode status = U_ZERO_ERROR;
        u_init(&status);
        if (U_FAILURE(status)) {
          cerr<< MODULENAME ": ICU library reports failure to initialize" << endl;
          return UIMA_ERR_USER_ANNOTATOR_COULD_NOT_INIT;
        }

        Py_Initialize();
      }

		//      main_module = PyImport_AddModule("__main__");
      if (PyImport_ImportModule("pythonnator") == 0) { 
        cerr << MODULENAME ":" << fn <<  ": failed to import pythonnator module, PYTHONPATH problem? " <<endl;
        return UIMA_ERR_USER_ANNOTATOR_COULD_NOT_INIT;
      }

      user_module = PyImport_ImportModule(srcfile);
      if (user_module == 0) {
        cerr << MODULENAME ": could not import python module " << srcfile <<endl;
        return UIMA_ERR_USER_ANNOTATOR_COULD_NOT_INIT;
      }
      dict = PyModule_GetDict(user_module);

      for (unsigned int i=0; i < FUNCTIONCOUNT; i++) {
        function[i] = PyDict_GetItemString(dict, function_name[i] );
        if (function[i]) {
          Py_INCREF(function[i]);
          if (debug>100) {
            cerr << MODULENAME ": Registered function " << 
		function_name[i] << endl;
          }
        } else {
          if (debug>100) {
            cerr << MODULENAME ": no function registered for " << 
		function_name[i] << endl;
          }
        }
      }

      // convert cas and rs to python variables (parameters) 
      swig_module_info *module = SWIG_Python_GetModule(NULL);
      if (!module) {
        cerr << MODULENAME ": could not get Python swig module" << endl;
        return UIMA_ERR_USER_ANNOTATOR_COULD_NOT_INIT;
      }

      ts_type = SWIG_TypeQueryModule(module,module, "_p_TypeSystem");
      if (!ts_type) {
        cerr << MODULENAME ": could lookup TypeSystem type in swig" << endl;
        return UIMA_ERR_USER_ANNOTATOR_COULD_NOT_INIT;
      }
      ac_type = SWIG_TypeQueryModule(module,module, "_p_AnnotatorContext");
      if (!ac_type) {
        cerr << MODULENAME ": could lookup AnnotatorContext type in swig" << endl;
        return UIMA_ERR_USER_ANNOTATOR_COULD_NOT_INIT;
      }
      cas_type = SWIG_TypeQueryModule(module,module, "_p_CAS");
      if (!cas_type) {
        cerr << MODULENAME ": could lookup cas type in swig" << endl;
        return UIMA_ERR_USER_ANNOTATOR_COULD_NOT_INIT;
      }
//       tcas_type = SWIG_TypeQueryModule(module,module, "_p_TCAS");
//       if (!tcas_type) {
//         cerr << MODULENAME ": could lookup tcas type in swig" << endl;
//         return UIMA_ERR_USER_ANNOTATOR_COULD_NOT_INIT;
//       }
      rs_type = SWIG_TypeQueryModule(module,module, 
	"_p_ResultSpecification");
      if (!rs_type) {
        cerr << MODULENAME ": could lookup rs type in swig" << endl;
        return UIMA_ERR_USER_ANNOTATOR_COULD_NOT_INIT;
      }

      if (function[FUNCTION_INITIALIZE]) {
        PyObject *arg1 = 
           SWIG_Python_NewPointerObj(NULL,
           reinterpret_cast<void *>( &ac),
           ac_type, 0);
        PyObject *rv = PyObject_CallFunctionObjArgs( 
		function[FUNCTION_INITIALIZE], arg1, NULL);
        Py_DECREF(arg1);
        if (rv == 0) {
          cerr << MODULENAME ": python error " << endl;
          PyErr_Print();
          return UIMA_ERR_USER_ANNOTATOR_COULD_NOT_INIT;
        } 
        Py_DECREF(rv);
      }

      return UIMA_ERR_NONE;
  }

  TyErrorId reconfigure() {
    if (refcount==0) {
      cerr << MODULENAME ": not initialized in reconfigure" << endl;
      return UIMA_ERR_USER_ANNOTATOR_COULD_NOT_INIT;
    }
    if (debug > 100) {
      cerr<< MODULENAME ": reconfigure" <<endl;
    }
    if (function[FUNCTION_RECONFIGURE]) {
      PyObject *rv = PyObject_CallFunctionObjArgs( 
        function[FUNCTION_RECONFIGURE], NULL);
      if (rv == 0) {
        cerr << MODULENAME ": python error " << endl;
        PyErr_Print();
        return UIMA_ERR_USER_ANNOTATOR_COULD_NOT_INIT;
      }
      Py_DECREF(rv);
    }
    return UIMA_ERR_NONE;
  }

  TyErrorId typeSystemInit(TypeSystem const &ts) {
    if (refcount==0) {
      cerr << MODULENAME ": not initialized in typeSystemInit" << endl;
      return UIMA_ERR_USER_ANNOTATOR_COULD_NOT_INIT;
    }
    if (debug > 100) {
      cerr<< MODULENAME ": typeSystemInit" <<endl;
    }
    if (function[FUNCTION_TYPESYSTEMINIT] == 0) return UIMA_ERR_NONE;
    PyObject *arg1 = 
       SWIG_Python_NewPointerObj(NULL,
       reinterpret_cast<void *>( const_cast<TypeSystem *>(&ts)),
       ts_type, 0);
    PyObject *rv = PyObject_CallFunctionObjArgs( 
		function[FUNCTION_TYPESYSTEMINIT], arg1, NULL);
    Py_DECREF(arg1);

    if (rv == 0) {
      cerr << MODULENAME ": python error " << endl;
      PyErr_Print();
      return UIMA_ERR_USER_ANNOTATOR_COULD_NOT_INIT;
    } else {
      Py_DECREF(rv);
    }
    return UIMA_ERR_NONE;
  }

/** 
 * call the UIMA Annotator to deinitialize itself based on a UIMA engine
 * and return a UIMA error code
 */
  TyErrorId destroy()
  { 
    if (debug > 100) {
      cerr<< MODULENAME ": destroy " << endl;
    }
    if (function[FUNCTION_DESTROY] != 0) {
      PyObject *rv = PyObject_CallFunctionObjArgs( 
        function[FUNCTION_DESTROY], NULL);
      if (rv == 0) {
        cerr << MODULENAME ": python error on destroy - ignoring" << endl;
        PyErr_Print();
      } else {
        Py_DECREF(rv);
      }
    }
    for (unsigned int i=0; i < FUNCTIONCOUNT; i++) {
      if (function[i]) Py_DECREF(function[i]);
      function[i] = 0;
    }

    if (--refcount == 0) {
      Py_Finalize();
#ifdef REBIND_PYTHON_SO
      dlclose(library); 
#endif
    } else {
      // Py_EndInterpreter is crashing with multiple pythonnators running in parallel
      // Py_EndInterpreter(thread_state);
      thread_state = 0;
    }
    return (TyErrorId)UIMA_ERR_NONE;
  }

/**
 * call the UIMA Annotator to perform its duty based on a UIMA engine
 * and return a UIMA error code
 */
  TyErrorId process(CAS &_cas, ResultSpecification const & _rs) { 
    if (debug > 100) {
      cerr<< MODULENAME ": process " << endl;
    }

    TyErrorId rc = UIMA_ERR_NONE;
    if (function[FUNCTION_PROCESS]==0) {
      return UIMA_ERR_NONE;
    }

    PyObject *arg1 = 
       SWIG_Python_NewPointerObj(NULL,
       reinterpret_cast<void *>( &_cas), cas_type, 0);
    if (!arg1) {
      cerr << "process: could not allocate Python object for cas" << endl;
      return UIMA_ERR_USER_ANNOTATOR_COULD_NOT_PROCESS;
    }
    PyObject *arg2 = 
       SWIG_Python_NewPointerObj(NULL,
       reinterpret_cast<void *>( 
		const_cast<ResultSpecification *>(&_rs)),
       rs_type, 0);
    if (!arg2) {
      Py_DECREF(arg1);
      cerr << "process: could not allocate Python object for resultspec"<<endl;
      return UIMA_ERR_USER_ANNOTATOR_COULD_NOT_PROCESS;
    }

    PyObject *rv = PyObject_CallFunctionObjArgs( 
		function[FUNCTION_PROCESS], arg1, arg2, NULL);

    Py_DECREF(arg2);
    Py_DECREF(arg1);

    if (rv == 0) {
      cerr << MODULENAME ": python error " << endl;
      PyErr_Print();
      rc = UIMA_ERR_USER_ANNOTATOR_COULD_NOT_PROCESS;
    } else {
      Py_DECREF(rv);
    }

    return rc;
  }

  TyErrorId batchProcessComplete()
  {
    if (debug > 100) {
      cerr<< MODULENAME ": batchProcessComplete " << endl;
    }
    if (function[FUNCTION_BATCHPROCESSCOMPLETE]) {
      PyObject *rv = PyObject_CallFunctionObjArgs( 
        function[FUNCTION_BATCHPROCESSCOMPLETE], NULL);
      if (rv == 0) {
        cerr << MODULENAME ": python error " << endl;
        PyErr_Print();
        return UIMA_ERR_USER_ANNOTATOR_COULD_NOT_INIT;
      }
      Py_DECREF(rv);
    }
    return (TyErrorId)UIMA_ERR_NONE;
  }

  TyErrorId collectionProcessComplete()
  {
    if (debug > 100) {
      cerr<< MODULENAME ": collectionProcessComplete " << endl;
    }
    if (function[FUNCTION_COLLECTIONPROCESSCOMPLETE]) {
      PyObject *rv = PyObject_CallFunctionObjArgs( 
        function[FUNCTION_COLLECTIONPROCESSCOMPLETE], NULL);
      if (rv == 0) {
        cerr << MODULENAME ": python error " << endl;
        PyErr_Print();
        return UIMA_ERR_USER_ANNOTATOR_COULD_NOT_INIT;
      }
      Py_DECREF(rv);
    }
    return (TyErrorId)UIMA_ERR_NONE;
  }

};

#ifdef REBIND_PYTHON_SO
void *Pythonnator::library = 0;
#endif
unsigned int Pythonnator::refcount = 0;

MAKE_AE(Pythonnator);


// /* ----------------------------------------------------------------------- */
// /*   Mapping for generic C API wrapper                                     */
// /* ----------------------------------------------------------------------- */

// typedef Pythonnator UserDefinedAnnotator;
// // define for error/exception info in uima_annotator_generic.inl
// #define UIMA_ANNOTATOR_NAME MODULENAME

// /* ----------------------------------------------------------------------- */
// /*   Include generic C API wrapper                                         */
// /* ----------------------------------------------------------------------- */

// // use casconsumer version so that both annotators and casconsumers are supported
// #include "uima_casconsumer_generic.inl"


/* <EOF> */


