#include <boost/python.hpp>
#include <boost/python/manage_new_object.hpp>
#include <boost/python/copy_const_reference.hpp>
#include <boost/python/return_value_policy.hpp>
#include <boost/python/extract.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
#include <string>
#include <RTSMonitoringTask.h>
//#include <RTSResult.h>
#include <RTSErrResult.h>
#include <RelGILLock.h>
#include <GILLock.h>


struct RTService
{
 private:
     /* data */

    //RTSMonitoringTask rtsMonTask;
    RTSCoproHelper rtsCopro;

 public:

    //  RT_Service(/* args */) {
    //  }

    //  ~RT_Service() {}

    bool isCoproRunning(){
        PyRelinquishGIL scoped;
        return rtsCopro.Copro_isFwRunning();
    }

    bool initCoproFW(std::string fwPath, std::string fwName){
        PyRelinquishGIL scoped;
        return rtsCopro.Init(fwPath, fwName);
    }

    // bool initLogChannel(){
    //     PyRelinquishGIL scoped;
    //     return rtsCopro.Copro_initLogChannel();
    // }

    // bool openLogChannel(){
    //     PyRelinquishGIL scoped;
    //     return rtsCopro.Copro_initLogChannel();
    // }

    // bool writeLogChannel(){
    //     PyRelinquishGIL scoped;
    //     return rtsCopro.Copro_writeLogChannel();
    // }

    // std::string readLogChannel(){
    //     PyRelinquishGIL scoped;
    //     return rtsCopro.Copro_readLogChannel();
    // }

    // bool closeLogChannel(){
    //     PyRelinquishGIL scoped;
    //     return rtsCopro.Copro_closeLogChannel();
    // }

    // int openDataChannel(std::string monfilename){
    //     PyRelinquishGIL scoped;
    //     return rtsMonTask.Open(monfilename);
    // }

    // std::string readDataChannel(int fileDesc){
    //     PyRelinquishGIL scoped;
    //     return rtsMonTask.Read(fileDesc);
    // }

    // bool closeDataChannel(int fileDesc){
    //     PyRelinquishGIL scoped;
    //     return rtsMonTask.Close(fileDesc);
    // }

    boost::python::list getMonitoringStates() {
        //TODO ask the M4Core for the Monitpring Status
        PyRelinquishGIL scoped;        
        boost::python::list list;        
        return list;
    }

    // we need all parameters like id, samplerate, sampletime, downtime, later: HW-channels with the configurations
    // bool startMonitoring(int samplerate, int sampleperiod, int downtime, std::string status) { 
    //     PyRelinquishGIL scoped;
    //     //TODO ML: add this to the M4Core
    //     // if (rtsMonTask.Init()) {
    //         return rtsMonTask.Start(samplerate, sampleperiod, downtime);
    //     // }
    //     // return false;
    // }
    // we need all parameters like id, samplerate, sampletime, downtime, later: HW-channels with the configurations
    // bool stopMonitoring(std::string id) { 
    //     PyRelinquishGIL scoped;
    //     //TODO ML: add this to the M4Core
    //     // if (rtsMonTask.Init()) {
    //         return rtsMonTask.Stop(id);
    //     // }
    //     // return false;
    // }


};



using namespace boost::python;

BOOST_PYTHON_MODULE(rt_service)
{

    namespace python = boost::python;
    // python::class_<RTSMonScript, boost::noncopyable>("RTSMonitoring", python::no_init)
    //     .add_property("id", &RTSMonitoring::GetId, &RTSMonitoring::SetId)
    //     .add_property("samplerate", &RTSMonitoring::GetSampleRate, &RTSMonitoring::SetId)
    //     .add_property("samplePeriod", &RTSMonitoring::GetSamplePeriod, &RTSMonitoring::SetId)
    //     .add_property("downtime", &RTSMonitoring::GetDownTime, &RTSMonitoring::SetId)

    //     .def("add2Script", pure_virtual(&RTSMonitoring::add2Script))
    // ;

    // class_<std::vector<RTSMonitoring*>>("RTSMonitoringList")
    //     .def(vector_indexing_suite<std::vector<RTSMonitoring*>>())
    //     ;

    // def("add2Script", +[](RTSMonitoring* object) {
    //     return object->add2Script();
    // });

    //, python::init<PyObject*>()
    class_<RTSMonitoringTask, boost::noncopyable>("RTSMonitoringTask", init<std::string, std::string, int, int, int, std::string>())
        // .add_property("id", &RTSMonitoringTask::GetId, &RTSMonitoringTask::SetId)
        // .add_property("samplerate", &RTSMonitoringTask::GetRate, &RTSMonitoringTask::SetRate)
        // .add_property("samplePeriod", &RTSMonitoringTask::GetPeriod, &RTSMonitoringTask::SetPeriod)
        // .add_property("downtime", &RTSMonitoringTask::GetDowntime, &RTSMonitoringTask::SetDowntime)
        // .add_property("path", &RTSMonitoringTask::GetPath, &RTSMonitoringTask::SetPath)        
        .def("start", &RTSMonitoringTask::Start) 
        .def("stop", &RTSMonitoringTask::Stop)
        .def_readonly("id", &RTSMonitoringTask::id)
        .def_readonly("name", &RTSMonitoringTask::monName)
        .def_readonly("samplerate", &RTSMonitoringTask::samplerate)        
        .def_readonly("sampleperiod", &RTSMonitoringTask::sampleperiod)        
        .def_readonly("downtime", &RTSMonitoringTask::downtime)        
        .def_readonly("path", &RTSMonitoringTask::path)        
        // .def("openChannel", &RTSMonitoringTask::Open) //, return_value_policy<manage_new_object>())  
        // .def("readChannel", &RTSMonitoringTask::Read)        
        // .def("closeChannel", &RTSMonitoringTask::Close)
        // .def("getLogMsg", &RTSMonitoringTask::GetLogMsg) //, return_value_policy<manage_new_object>())
        // .def("getExtError", &RTSMonitoringTask::GetExtError, return_value_policy<manage_new_object>())        
    ;

    class_<RTService>("RT_Service")
        .def("isCoproRunning", &RTService::isCoproRunning)
        .def("initCoproFW", &RTService::initCoproFW)
        // .def("initLogChannel", &RTService::initLogChannel)
        // .def("readLogChannel", &RTService::readLogChannel)
        .def("getAllMonitoringStat", &RTService::getMonitoringStates)        
        // .def("startMonitoring", &RTService::startMonitoring)  
        // .def("stopMonitoring", &RTService::stopMonitoring)
        // .def("openDataChannel", &RTService::openDataChannel)  
        // .def("readDataChannel", &RTService::readDataChannel)        
        // .def("closeDataChannel", &RTService::closeDataChannel)        
    ;

     class_<RTSResult>("RTSResult")
        .def("getResCode", &RTSResult::getResCode)
        .def("getMsg", &RTSResult::getMsg)        
        // .def("getProps", &RTSResult::getProps , return_value_policy<copy_const_reference>())
       ;

    // class_<RTSResult, boost::noncopyable>("RTSResult", init<std::string>())
    //     .def("getResCode", &RTSResult::getResCode)
    //     .def("getProperties", &RTSResult::getProperties, return_value_policy<copy_const_reference>())
    //    ;

};


/** 
 *  startmonitoring()
 *  stopmonitoring(id)

        .def("createMonitoring", &RTService::createMonitoring)
        .def("setMonitoringStatus", &RTService::setMonitoringStatus)
        .def("getMonitoringStatus", &RTService::getMonitoringState)



*/
