from twisted.internet import defer, reactor, task
from twisted.python import reflect
import logging

log = logging.getLogger("Observatory")

class fakeWheather:

   status = 'Unknown'

   def __init__(self):
      log.debug("Requesting wheather for an unknown observatory")

   def startCron(self):
      return True

   def stopCron(self):
      return True


class fakeDome:

   status = 'Unknown'

   def __init__(self):
      log.debug("Requesting dome status for an unknown observatory")

   def startCron(self):
      return True

   def stopCron(self):
      return True


class Observatory:

   observatoryes = {}
   oblist = []
   sameasdomelist = {}
   sameaswheatherlist = {}

   def __init__(self, parent, cfg=None):
      self.parent = parent
      self.cfg = self.parent.observatorycfg

   def initialize(self):
      self.initObs().addErrback(lambda _: "Error initializing observatoryes")

   def initObs(self):
      self.oblist = self.cfg.sections()
      self.oblist.append('Unknown')
      for obs in self.oblist:
         dome = False
         wheather = False
         self.observatoryes[obs] = {'tlist': {}}
         try:
            #ob = __import__("observatoryes."+obs, globals(), locals(), [''])
            ob = reflect.namedAny("observatoryes."+obs)
            try:
               dome = ob.dome()
            except:
               pass
            try:
               wheather = ob.wheather()
            except:
               pass
         except:
            pass
         if dome:
            self.observatoryes[obs]['domeobj'] = dome
         else:
            self.observatoryes[obs]['domeobj'] = fakeDome()
         if wheather:
            self.observatoryes[obs]['wheatherobj'] = wheather
         else:
            self.observatoryes[obs]['wheatherobj'] = fakeWheather()
         self.observatoryes[obs]['domeobj'].command = self.Command_From_OBS
         self.observatoryes[obs]['wheatherobj'].command = self.Command_From_OBS
         self.observatoryes[obs]['domeobj'].startCron()
         self.observatoryes[obs]['wheatherobj'].startCron()
      self.sameasdomelist = {}
      self.sameaswheatherlist = {}
      for obs in self.oblist:
         try:
            sameas = self.observatoryes[obs]['domeobj'].sameas
            if sameas in self.oblist:
               if sameas in self.sameasdomelist.keys():
                  self.sameasdomelist.append(obs)
               else:
                  self.sameasdomelist[sameas] = [obs]
         except:
            pass

         try:
            sameas = self.observatoryes[obs]['wheatherobj'].sameas
            if sameas in self.oblist:
               if sameas in self.sameaswheatherlist.keys():
                  self.sameaswheatherlist.append(obs)
               else:
                  self.sameaswheatherlist[sameas] = [obs]
         except:
            pass

      return defer.succeed(True)

   def stopCron(self):
      log.debug("Stopping Cron check")
      for obs in self.observatoryes.keys():
         try:
            self.observatoryes[obs]['domeobj'].stopCron()
            del self.observatoryes[obs]['domeobj']
         except:
            pass
         try:
            self.observatoryes[obs]['wheatherobj'].stopCron()
            del self.observatoryes[obs]['wheatherobj']
         except:
            pass
      return defer.succeed(True)

   def reloadConfig(self):
      log.debug("Reloading Config")
      self.stopCron()
      self.observatoryes = {}
      self.oblist = []
      self.sameasdomelist = {}
      self.sameaswheatherlist = {}
      self.cfg = self.parent.observatorycfg
      self.initObs()
      return defer.succeed(True)

   def DelTel(self, tnum, obs):
      try:
         del self.observatoryes[obs]['tlist'][tnum]
      except:
         pass

   def AddTel(self, tnum, obs):
      try:
         self.observatoryes[obs]['tlist'][tnum] = True
      except:
         pass

   def Command_From_OBS(self, what, who):
      if what == 'WStatus':
         try:
            status = self.observatoryes[who]['wheatherobj'].status
            log.debug("Sending status "+status+" for "+who+" wheather")
            if who in self.observatoryes.keys():
               self.command({'setWhetherStatus': [self.observatoryes[who]['tlist'].keys(), who]})
            if who in self.sameaswheatherlist.keys():
               for sameas in self.sameaswheatherlist[who]:
                  self.observatoryes[sameas]['wheatherobj'].status = status
                  self.command({'setWhetherStatus': [self.observatoryes[sameas]['tlist'].keys(), sameas]})
         except:
            pass
      elif what == 'DStatus': 
         try:
            status = self.observatoryes[who]['domeobj'].status
            log.debug("Sending status "+status+" for "+who+" dome")
            if who in self.observatoryes.keys():
               self.command({'setDomeStatus': [self.observatoryes[who]['tlist'].keys(), who]})
            if who in self.sameasdomelist.keys():
               for sameas in self.sameasdomelist[who]:
                  self.observatoryes[sameas]['domeobj'].status = status
                  self.command({'setDomeStatus': [self.observatoryes[sameas]['tlist'].keys(), sameas]})
         except:
            pass
      else:
         log.debug("Calling back command "+str(what)+" "+str(who))
         return self.command({what: who})

   def command(self):
      """ to be overriden """
      log.debug("COMMAND FRO OBSERVATORY MUST BE OVERRIDED!")

      
