#
# rawReaderMonitor()
# author  Maurizio Nagni
# version 1.0 - 21 September 2005
#
# This is the main class for the managements of the Yoda monitoring.
#
# Parameters:
#

import os, sys, signal, logging, time
from ngn.pamela.process.RawReaderProcess import RawReaderProcess
from ngn.utils.benchmark import Benchmark
from ConfigParser import *

#-------- WARNING ---------- WARNING -------- WARNING ---------
#The packages below are not in the pythin official distribution
import _fam
#from ROOT import gROOT
#from Xlib import error
#-------- WARNING ---------- WARNING -------- WARNING ---------


class RawReaderMonitor:
    def __init__(self, logger, configFile):
        #--------- Environment variables ----------------
       	self.__logger 		= logger
	self.__configFile 	= configFile
	self.__config 		= ConfigParser()
	self.__config.read(configFile)
	self.__folderToMonitor	= ''
        self.__benchmarkOn      = False
        
                
	try:
            if (self.__config.has_option('RawReaderMonitor', 'folderToMonitor')):
                self.__folderToMonitor	= self.__config.get('RawReaderMonitor', 'folderToMonitor')
            if (self.__config.has_option('RawReaderMonitor', 'benchmarkFile')):
                self.__bench       = Benchmark(self.__config.get('RawReaderMonitor', 'benchmarkFile'))
                self.__benchmarkOn = True

        except NoSectionError, detail:
                self.__logger.info('Section missing in configuration file: ', detail)
		print 'Section missing in configuration file: ', detail
		sys.exit(1)
	except NoOptionError, detail:
                self.__logger.info('Wrong option in configuration file: ', detail)
		print 'Wrong option in configuration file: ', detail
		sys.exit(1)
        #--------- Environment variables ----------------

    def __del__(self):
        if (self.__benchmarkOn):
            self.__bench.close()
        
    def execute(self):
    #*****************************************************************************
    #*  FAMEvent Structure:
    #*
    #*  When a file/directory has been modified/deleted, fam will pass
    #*  a FAMEvent structure to the application (through the callback
    #*  in the FAMMonitorFile/Directory routines).  This structure will
    #*  describe what event happened to the file.  The different events
    #*  that can happen to a file are listed in the FAMCodes enum.
    #****************************************************************************
    # enum FAMCodes { FAMChanged=1, FAMDeleted=2, FAMStartExecuting=3, 
    #		FAMStopExecuting=4, FAMCreated=5, FAMMoved=6, 
    #		FAMAcknowledge=7, FAMExists=8, FAMEndExist=9 };
    #
    # typedef struct  FAMEvent {
    #    FAMConnection* fc;         /* The fam connection that event occurred on */
    #    FAMRequest fr;             /* Corresponds to the FamRequest from monitor */
    #    char *hostname;            /* host and filename - pointer to which */
    #    char filename[PATH_MAX];   /* file changed */
    #    void *userdata;            /* userdata associated with this monitor req. */
    #    enum FAMCodes code;        /* What happened to file - see above */
    # } FAMEvent;
    #
    #*/
      #--- Setup a monitor for new files into the pitHost directory ----
      signal.signal(signal.SIGCHLD, signal.SIG_IGN)
      conn          = _fam.open()
      request       = conn.monitorDirectory(self.__folderToMonitor, None)
      # Infinite loop waiting for new DAT file
      while True:
          event = conn.nextEvent()
          # has been created a new file?
          if event.code == 5:
              fileName = event.filename
              uploadedSize = 0
              time.sleep(5)
	      if (os.path.isdir(fileName)): continue
              self.__logger.info('Uploading ' + self.__folderToMonitor + '/' + fileName)
              while ((os.path.getsize(self.__folderToMonitor + '/' + fileName) - uploadedSize) > 0):
                  uploadedSize = os.path.getsize(self.__folderToMonitor + '/' + fileName)
                  time.sleep(5)

                  
              if (not os.path.isdir(fileName)) & (fileName.find(".pam") > -1):
                 #start thread
                 #-------------------------------
                 if (self.__benchmarkOn):
                       self.__bench.start(self.__folderToMonitor + '/', fileName, 'RawReader')
                 self.__logger.info('Starting RawReaderProcess for' + self.__folderToMonitor + '/' + fileName)
                 newProcess = RawReaderProcess(self.__folderToMonitor, self.__configFile, fileName, self.__logger)
                 newProcess.start()
                 while newProcess.isAlive(): pass
                 if (self.__benchmarkOn):
                     self.__bench.end()
                 #--------------------------------
                 #end thread
              else :
                  self.__logger.info('File not exist or not suitable')
                  #sys.stdout.flush()
                  #os.remove(self.__pitHost + fileName)
                

