/*
 Copyright 2019 Alain Dargelas

 Licensed 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.
 */

/*
 * File:   PythonAPI.cpp
 * Author: alain
 *
 * Created on May 13, 2017, 4:42 PM
 */

#include "SourceCompile/SymbolTable.h"
#include "Utils/StringUtils.h"
#include "Utils/FileUtils.h"
#include "CommandLine/CommandLineParser.h"
#include "ErrorReporting/ErrorContainer.h"
#include "SourceCompile/CompilationUnit.h"
#include "SourceCompile/PreprocessFile.h"
#include "SourceCompile/CompileSourceFile.h"
#include "SourceCompile/Compiler.h"
#include "SourceCompile/ParseFile.h"
#include "antlr4-runtime.h"
using namespace std;
using namespace antlr4;

#include "parser/SV3_1aParserBaseListener.h"

#include "API/SV3_1aPythonListener.h"

using namespace SURELOG;

#include <sstream>
#include <string>
#include <fstream>
#include <iostream>
#include <cstdio>
#include "Python.h"
#include "API/PythonAPI.h"
#include "API/SLAPI.h"
#include "API/slapi_wrap.cxx"
#include "API/slapi.h"
#include "API/vobjecttypes_py.h"
#include <cstdlib>
#include "SourceCompile/PythonListen.h"

std::string PythonAPI::m_invalidScriptResult = "INVALID_PYTHON_SCRIPT_RESULT";

PyThreadState* PythonAPI::m_mainThreadState = NULL;

std::string PythonAPI::m_programPath = "";

bool PythonAPI::m_listenerLoaded = false;

std::string PythonAPI::m_listenerScript;

bool PythonAPI::m_strictMode = false;

std::string PythonAPI::m_builtinPath;

PythonAPI::PythonAPI() {}

PythonAPI::PythonAPI(const PythonAPI& orig) {}

PythonAPI::~PythonAPI() {}

static struct PyModuleDef SLAPI_module = {PyModuleDef_HEAD_INIT,
                                          "slapi",
                                          NULL,
                                          -1,
                                          SwigMethods,
                                          NULL,
                                          NULL,
                                          NULL,
                                          NULL};

static PyObject* PyInit_slapi(void) { return PyModule_Create(&SLAPI_module); }

void PythonAPI::shutdown() {
  PyEval_RestoreThread(m_mainThreadState);
  Py_Finalize();
}

bool PythonAPI::loadScript(std::string name, bool check) {
  PyEval_AcquireThread(m_mainThreadState);
  bool status = loadScript_(name, check);
  PyEval_ReleaseThread(m_mainThreadState);
  return status;
}

bool PythonAPI::loadScript_(std::string name, bool check) {
  if (FileUtils::fileExists(name)) {
    FILE* fp = fopen(name.c_str(), "r");
    PyRun_SimpleFile(fp, name.c_str());
    PyErr_Print();
    fclose(fp);
    return true;
  } else {
    if (check)
      std::cout << "PYTHON API ERROR: Script \"" << name
                << "\" does not exist.\n";
  }
  return false;
}

PyThreadState* PythonAPI::initNewInterp() {
  PyEval_AcquireThread(m_mainThreadState);
  PyThreadState* interpState = Py_NewInterpreter();

  loadScriptsInInterp_();
  // PyEval_ReleaseThread(m_mainThreadState);

  PyEval_ReleaseThread(interpState);
  return interpState;
}

void PythonAPI::shutdown(PyThreadState* interp) {
  if (interp != m_mainThreadState) {
    PyEval_AcquireThread(interp);
    Py_EndInterpreter(interp);
    PyEval_ReleaseLock();
  }
}

void PythonAPI::loadScriptsInInterp_() {
  // Loads the python SWIG generated defs
  std::string script;
  for (auto s : slapi_scripts) {
    script += s;
  }
  for (auto s : slapi_types) {
    script += s;
  }
  PyRun_SimpleString(script.c_str());

  PyRun_SimpleString("import sys");
  PyRun_SimpleString("sys.path.append(\".\")");
  PyRun_SimpleString(
      std::string("sys.path.append(\"" + m_programPath + "\")").c_str());

  std::string waivers = m_programPath + "/python/slwaivers.py";
  bool waiverLoaded = loadScript_(waivers);
  waivers =  "/usr/lib/surelog/slwaivers.py";
  waiverLoaded = loadScript_(waivers) || waiverLoaded;
  waivers =  "/usr/local/lib/surelog/slwaivers.py";
  waiverLoaded = loadScript_(waivers) || waiverLoaded;
  waivers = "./slwaivers.py";
  waiverLoaded = loadScript_(waivers) || waiverLoaded;

  std::string format = m_programPath + "/python/slformatmsg.py";
  bool messageFormatLoaded = loadScript_(format);
  format = "/usr/lib/surelog/slformatmsg.py";
  messageFormatLoaded = loadScript_(format) || messageFormatLoaded;
  format = "/usr/local/lib/surelog/slformatmsg.py";
  messageFormatLoaded = loadScript_(format) || messageFormatLoaded;
  format = "./slformatmsg.py";
  messageFormatLoaded = loadScript_(format) || messageFormatLoaded;

  if (m_listenerScript != "") {
    if (FileUtils::fileExists(m_listenerScript)) {
      m_listenerLoaded = loadScript_(m_listenerScript);
    }
  }

  if (!m_listenerLoaded) {
    std::string listener =
        m_programPath + "/python/slSV3_1aPythonListener.py";
    if (FileUtils::fileExists(listener)) m_listenerScript = listener;
    m_listenerLoaded = loadScript_(listener);

    listener = "/usr/lib/surelog/slSV3_1aPythonListener.py";
    if (FileUtils::fileExists(listener)) m_listenerScript = listener;
    m_listenerLoaded = loadScript_(listener) || m_listenerLoaded;
    listener = "/usr/local/lib/surelog/slSV3_1aPythonListener.py";
    if (FileUtils::fileExists(listener)) m_listenerScript = listener;
    m_listenerLoaded = loadScript_(listener) || m_listenerLoaded;
    listener = "./slSV3_1aPythonListener.py";
    if (FileUtils::fileExists(listener)) m_listenerScript = listener;
    m_listenerLoaded = loadScript_(listener) || m_listenerLoaded;
  }
}

void PythonAPI::init(int argc, const char** argv) {
  m_programPath = argv[0];
  m_programPath = StringUtils::rtrim(m_programPath, '/');
  for (int i = 1; i < argc; i++) {
      if (!strcmp(argv[i], "-builtin")) {
          if (i < argc - 1) {
            m_builtinPath = argv[i + 1];
          }
      }
  }
  // Before Python 3.7, the parameter to SetProgramName() was not a
  // const wchar_t* but a wchar_t (even though never written to).
  static wchar_t progname[] = L"surelog";
  Py_SetProgramName(progname);

  PyImport_AppendInittab("slapi", &PyInit_slapi);

  Py_Initialize();
  PyEval_InitThreads();
  m_mainThreadState = PyEval_SaveThread();
  PyEval_AcquireThread(m_mainThreadState);

  loadScriptsInInterp_();

  PyEval_ReleaseThread(m_mainThreadState);
}

void PythonAPI::evalScript(std::string function, SV3_1aPythonListener* listener,
                           ParserRuleContext* ctx) {
  PyEval_AcquireThread(listener->getPyThreadState());
  PyObject *pModuleName, *pModule, *pFunc;
  PyObject *pArgs, *pValue;
  pModuleName = PyString_FromString("__main__");
  pModule = PyImport_Import(pModuleName);
  Py_DECREF(pModuleName);
  pFunc = PyObject_GetAttrString(pModule, function.c_str());
  if (!pFunc || !PyCallable_Check(pFunc)) {
    if (m_strictMode)
      std::cout << "PYTHON API ERROR: Function \"" << function
                << "\" does not exist.\n";
    PyEval_ReleaseThread(listener->getPyThreadState());
    return;
  }
  pArgs = PyTuple_New(2);
  pValue = SWIG_NewPointerObj(SWIG_as_voidptr(listener),
                              SWIGTYPE_p_SURELOG__SV3_1aPythonListener, 0 | 0);
  PyTuple_SetItem(pArgs, 0, pValue);
  pValue = SWIG_NewPointerObj(SWIG_as_voidptr(ctx),
                              SWIGTYPE_p_ParserRuleContext, 0 | 0);
  PyTuple_SetItem(pArgs, 1, pValue);
  PyObject_CallObject(pFunc, pArgs);
  PyErr_Print();
  Py_DECREF(pArgs);
  Py_XDECREF(pFunc);
  Py_DECREF(pModule);
  PyEval_ReleaseThread(listener->getPyThreadState());
}

std::string PythonAPI::evalScript(std::string module, std::string function,
                                  std::vector<std::string> args,
                                  PyThreadState* interp) {
  PyEval_AcquireThread(interp);

  std::string result;
  PyObject *pModuleName, *pModule, *pFunc;
  PyObject *pArgs, *pValue;

  pModuleName = PyString_FromString(module.c_str());
  pModule = PyImport_Import(pModuleName);

  Py_DECREF(pModuleName);
  if (pModule != NULL) {
    pFunc = PyObject_GetAttrString(pModule, function.c_str());
    /* pFunc is a new reference */

    if (pFunc && PyCallable_Check(pFunc)) {
      pArgs = PyTuple_New(args.size());
      for (unsigned int i = 0; i < args.size(); ++i) {
        pValue = PyString_FromString(args[i].c_str());
        /* pValue reference stolen here: */
        PyTuple_SetItem(pArgs, i, pValue);
      }
      pValue = PyObject_CallObject(pFunc, pArgs);
      Py_DECREF(pArgs);
      if (pValue != NULL) {
        Py_ssize_t size;
        const char* compName = PyUnicode_AsUTF8AndSize(pValue, &size);
        if (compName == NULL) {
          std::cout << "PYTHON API ERROR: Incorrect function return type, "
                       "expecting a string: "
                    << function << std::endl;
          Py_DECREF(pValue);

          PyEval_ReleaseThread(interp);
          return m_invalidScriptResult;
        }
        result = compName;
        Py_DECREF(pValue);
      } else {
        Py_DECREF(pFunc);
        Py_DECREF(pModule);
        PyErr_Print();
        std::cout << "PYTHON API ERROR: Incorrect function evaluation: "
                  << function << std::endl;
        PyEval_ReleaseThread(interp);
        return m_invalidScriptResult;
      }
    } else {
      if (PyErr_Occurred()) PyErr_Print();
      std::cout << "PYTHON API ERROR: Cannot find function " << function
                << std::endl;

      PyEval_ReleaseThread(interp);
      return m_invalidScriptResult;
    }
    Py_XDECREF(pFunc);
    Py_DECREF(pModule);
  } else {
    PyErr_Print();
    std::cout << "PYTHON API ERROR: Cannot load module " << module << std::endl;
    return m_invalidScriptResult;
  }

  PyEval_ReleaseThread(interp);
  return result;
}

bool PythonAPI::evalScriptPerFile(std::string script, ErrorContainer* errors,
                                  FileContent* fC, PyThreadState* interp) {
  PyEval_AcquireThread(interp);
  loadScript_(script);
  std::string function = "slUserCallbackPerFile";
  PyObject *pModuleName, *pModule, *pFunc;
  PyObject *pArgs, *pValue;
  pModuleName = PyString_FromString("__main__");
  pModule = PyImport_Import(pModuleName);
  Py_DECREF(pModuleName);
  pFunc = PyObject_GetAttrString(pModule, function.c_str());
  if (!pFunc || !PyCallable_Check(pFunc)) {
    std::cout << "PYTHON API ERROR: Function \"" << function
              << "\" does not exist.\n";
    PyEval_ReleaseThread(interp);
    return false;
  }
  pArgs = PyTuple_New(2);
  pValue = SWIG_NewPointerObj(SWIG_as_voidptr(errors),
                              SWIGTYPE_p_SURELOG__ErrorContainer, 0 | 0);
  PyTuple_SetItem(pArgs, 0, pValue);
  pValue = SWIG_NewPointerObj(SWIG_as_voidptr(fC),
                              SWIGTYPE_p_SURELOG__FileContent, 0 | 0);
  PyTuple_SetItem(pArgs, 1, pValue);

  PyObject_CallObject(pFunc, pArgs);
  PyErr_Print();
  Py_DECREF(pArgs);
  Py_XDECREF(pFunc);
  Py_DECREF(pModule);

  PyEval_ReleaseThread(interp);
  return true;
}

bool PythonAPI::evalScript(std::string script, Design* design) {
  PyEval_AcquireThread(m_mainThreadState);
  loadScript_(script);
  std::string function = "slUserCallbackPerDesign";
  PyObject *pModuleName, *pModule, *pFunc;
  PyObject *pArgs, *pValue;
  pModuleName = PyString_FromString("__main__");
  pModule = PyImport_Import(pModuleName);
  Py_DECREF(pModuleName);
  pFunc = PyObject_GetAttrString(pModule, function.c_str());
  if (!pFunc || !PyCallable_Check(pFunc)) {
    std::cout << "PYTHON API ERROR: Function \"" << function
              << "\" does not exist.\n";
    PyEval_ReleaseThread(m_mainThreadState);
    return false;
  }
  pArgs = PyTuple_New(2);
  pValue = SWIG_NewPointerObj(
      SWIG_as_voidptr(design->getCompiler()->getErrorContainer()),
      SWIGTYPE_p_SURELOG__ErrorContainer, 0 | 0);
  PyTuple_SetItem(pArgs, 0, pValue);
  pValue = SWIG_NewPointerObj(SWIG_as_voidptr(design),
                              SWIGTYPE_p_SURELOG__Design, 0 | 0);
  PyTuple_SetItem(pArgs, 1, pValue);
  PyObject_CallObject(pFunc, pArgs);
  PyErr_Print();
  Py_DECREF(pArgs);
  Py_XDECREF(pFunc);
  Py_DECREF(pModule);

  PyEval_ReleaseThread(m_mainThreadState);
  return true;
}
