import uuid
import datetime as dt
from marshmallow import Schema, fields, post_load

from vrpmdvcreatemoncmd import VRPMDV_CreateMonCmd
from vrpmdvcreatemonschema import VRPMDV_CreateMonSchema
from vrpmdvdeletemoncmd import VRPMDV_DeleteMonCmd
from vrpmdvdeletemonschema import VRPMDV_DeleteMonSchema
from vrpmdvmonreq import VRPMDV_MonReq
from extensions.rt_service import rt_service as rts
from vrpmdvmonitoringState import VRPMDVMonitoringState
from vrpmdvmondata import createCoproLoggingTask
# from vrpmdvntlink import trySend
import logging
import threading
import time

import io
import fcntl
import mmap

from vrpmdvntlink import trySend
from vrpmdvstatusmoncmd import VRPMDV_StatusMonCmd
from vrpmdvstatusmonschema import VRPMDV_StatusMonSchema


# def thread_function(name):

#     logging.info("MonThread %s: starting", name)
#     fdesc = -1
#     rtMon = rts.RTSMonitoringTask()
#     fdesc = rtMon.openChannel('/dev/mon-datafile')
    
#     # write loginfos to Buffer
#     msg = rtMon.getLogMsg()
#     for msgstr in msg:
#         logging.info(str(msgstr))

#     while ((fdesc >= 0) && ()):
#             msg = rtMon.readChannel(fdesc)
#             # write loginfos to Buffer
#             logmsg = rtMon.getLogMsg()
#             for msgstr in logmsg:
#                 logging.info(str(msgstr))

#             logging.info(msg)
#             if (msg == 'noResult'):
#                  break
    
#     logging.info("MonThread %s: finishing", name)
#     rtMon.closeChannel(fdesc)

    # if (res):    
    #     props = res.getMsg()        
    #     #props = res.getProps()        
    #     if (res.getResCode() == 'error'):
    #         try:
    #             logging.info(props)
    #             # for key, value in props.items():
    #             #     logging.info(key+" "+ str(value))
    #         except:
    #             logging.info("MonThread %s: could not open the channel", name)         
    #     else:
    #         try:
    #             logging.info(props)                
    #             # for key, value in props.items():
    #             #     logging.info(key+" "+ str(value))
    #         except:
    #             logging.info("MonThread %s: could read fdesc of the channel", name)         
    # else :
    #     logging.info("MonThread %s: result = None", name)                 





class VRPMDV_Monitoring(VRPMDV_MonReq):
    def __init__(self, no, id, name , samplerate, sampleperiod, downtime, status, owner="None", created_at=dt.datetime.now()) :
        self.no = no
        self.id =  id
        self.created_at = created_at
        #TODO ML: uncomment
        self.rtservice = None #rts.RT_Service()
        self.rtMon = None
        self.monTask = None
        self.run_thread = False
        self.fdesc = -1
        super().__init__(name, samplerate, sampleperiod, downtime, owner, status)

   
    def startMonitoring(self) :
        #send create command to M4
        try :
            logging.basicConfig(format=format, level=logging.INFO, datefmt="%H:%M:%S")            
            logging.info("MainThread: createMonOnDevice => before vrpmdCreateCmd samplerate:%d, samplerate:%d, samplerate:%d", self.samplerate, self.sampleperiod, self.downtime)                        
            vrpmdCreateCmd = VRPMDV_CreateMonCmd(self.samplerate, self.sampleperiod, self.downtime)
            logging.info("MainThread: createMonOnDevice => before schemaCreateCmd")                                    
            schemaCreateCmd = VRPMDV_CreateMonSchema() 
            logging.info("MainThread: try send start monitoring starting %s", schemaCreateCmd.dumps(vrpmdCreateCmd))                        
            # TODO ML: uncomment this
            res = trySend(schemaCreateCmd.dumps(vrpmdCreateCmd))
            #res = 'Test'
            logging.info("MainThread: try send start monitoring done %s", res)                                    

            # start the receiving thread
            logging.info("MainThread %s: open", str(self.id))
            # self.fdesc = self.rtMon.openChannel('/dev/mon-datafile')

            # self.run_thread = True
            # self.monTask = threading.Thread(target=self.run, args=())
            # self.monTask.start()
            # logging.info("MainThread: strated Mon Thread %s started", self.id)
            logging.info("startmonitoring: create RTSMonitoringTask")
            strid = str(self.id)
            logging.info("rts.RTSMonitoringTask: self.id:%s", strid)
            self.rtMon = rts.RTSMonitoringTask(str(self.id), str(self.name), self.samplerate, self.sampleperiod, self.downtime, '/home/root/monfiles/')
            # self.rtMon.id = self.id
            # self.rtMon.name = self.name
            # self.rtMon.samplerate = self.samplerate
            # self.rtMon.samplePeriod = self.sampleperiod
            # self.rtMon.downtime = self.downtime
            # self.rtMon.path = '/home/root/monfiles'
            #logging.info("startmonitoring: created RTSMonitoringTask: id:%s name:%s samplerate:%d sampleperiod:%d downtime:%d path:%s", self.rtMon.id, self.rtMon.name, self.rtMon.samplerate, self.rtMon.samplePeriod, self.rtMon.downtime, self.rtMon.path)

            ##new ML 09.07.2024
            if (self.rtMon.start()) :
                logging.info("startmonitoring - self.rtMon.start(): Monitoring started")

                self.status = 'started'
            else :
                self.status = 'stopped'
            return self.status
        except :
            self.status = "stopped"
            self.rtMon = None
            return self.status        
    
    def stopMonitoring(self) :
        # isstopped = self.rtservice.setMonitoringState(str(self.id), VRPMDVMonitoringState.stopped)
        logging.basicConfig(format=format, level=logging.INFO, datefmt="%H:%M:%S")#  
        logging.info("MainThread: stopping Mon Thread %s ", self.id) 
        #send delete cmd to M4
        #logging.info("MainThread: stop monitoring")


        # if (self.monTask != None) :                
            # set the value Runthread to fals that the thread terminate
            # self.run_thread = False
            # self.monTask.join(None)

            ##new ML 09.07.2024
        if (self.rtMon != None) :
            self.rtMon.stop()            
            # self.monTask = None
            # logging.info("MonThread %s: closing fdesc=%s", str(self.id), str(self.fdesc))
            # # self.rtMon.closeChannel(self.fdesc)
            # logging.info("MonThread %s: closed fdesc=%s", str(self.id), str(self.fdesc))            

        logging.info("MainThread: stopped Mon Thread %s ", self.id) 

        vrpmdDeleteCmd = VRPMDV_DeleteMonCmd(self.no)
        schemaDeleteCmd = VRPMDV_DeleteMonSchema() 
        # TODO ML: uncomment this
        res = trySend(schemaDeleteCmd.dumps(vrpmdDeleteCmd))
        #res = 'Stopped'
        logging.info("MainThread: try send stop monitoring done %s", res)                                    

        self.rtMon = None
        # if (isstopped) :
        self.status = 'stopped'
        return self.status        
    
    # def setStatus(self, status) :
    #     # isStatusSet = self.rtservice.setMonitoringStatus(str(self.id), status) 
    #     logging.info("MainThread: set status ")                                
    #     return True

    def run(self):

        # logging.info("MonThread %s: starting", str(self.id))
        # fdesc = -1
        # rtMon = rts.RTSMonitoringTask()
        # fdesc = rtMon.openChannel('/dev/mon-datafile')
        
        # write loginfos to Buffer
        # msg = rtMon.getLogMsg()
        # for msgstr in msg:
        #     logging.info(str(msgstr))

        count = 0;
        if (self.fdesc >= 0) :
            while (self.run_thread):
                # check if the thread is running
                # if (count == 50): 
                #     vrpmdStatusCmd = VRPMDV_StatusMonCmd(self.no)
                #     schemaStatusCmd = VRPMDV_StatusMonSchema()     
                #     res = trySend(schemaStatusCmd.dumps(vrpmdStatusCmd))
                #     logging.info("MainThread: try send stop monitoring done %s", res)                                    
                #     count = 0
                #count = count +1
                
                msg = self.rtMon.readChannel(self.fdesc)
                logging.info("MonThread %s: running", str(self.id))
                logging.info("Result: %s", msg)
                #time.sleep(1)
                
                # write loginfos to Buffer
                # logmsg = rtMon.getLogMsg()
                # for msgstr in logmsg:
                #     logging.info(str(msgstr))

                # logging.info(msg)
                # if (msg == 'noResult'):
                #     break
            
            # logging.info("MonThread %s: finishing", str(self.id))
            # rtMon.closeChannel(fdesc)
            logging.info("MonThread %s: finished", str(self.id))            
            # msg = rtMon.getLogMsg()
            # for msgstr in msg:
            #     logging.info(str(msgstr))
        else:
            logging.info("MonThread %s: opening failed fdesc <= 0", str(self.id))
