#!/usr/bin/env python2.5
from twisted.internet import ssl, epollreactor
epollreactor.install()
from twisted.internet import reactor
reactor.suggestThreadPoolSize(30)

from twisted.application import service, internet, app, reactors
from twisted.web import server
import logging, time, sys, os
from skyliveDaemon.daemonizer import Daemonizer
from skyliveDaemon import skylived, clientproto, lx200proto
from skyliveDaemon.utils.genutils import configFile
from logging import handlers as loghandlers
from nevow import appserver   

# file di log da 100 mega, per 5 rotazioni 
filedebug = loghandlers.RotatingFileHandler(
      os.path.abspath(os.path.dirname(sys.argv[0]))+'/logs/skylived.log', 'a', 104857600, 5)
filedebug.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s => %(name)-12s: %(levelname)-8s %(message)s')
filedebug.setFormatter(formatter)
logging.basicConfig()

class skylivedDaemon(Daemonizer):

  # XXX TODO: come gestire il cambio di uid a un utente non root?
  #           si potrebbe fare anche da start-stop-daemon di debian,
  #           ma se si puo' fare da qui lo preferisco!

  def __init__(self):
    self.curdir = os.path.abspath(os.path.dirname(sys.argv[0]))
    log.debug("Reading daemon Config file")
    self.daemoncfg = configFile(self.curdir+'/conf/skylived.conf')
    self.daemoncfg.readConfig()
    try:
      debug = self.daemoncfg.get('general', 'debug')
      if debug == '0' or debug == 'no' or debug == 'warning':
         filedebug.setLevel(logging.WARNING)
      elif debug == '1' or debug == 'info':
         filedebug.setLevel(logging.INFO)
      elif debug == '2' or debug == 'debug' or debug == 'yes':
         filedebug.setLevel(logging.DEBUG)
    except:
      pass
    log.debug("Daemonizing process")
    Daemonizer.__init__(self, self.curdir+'/run/skylived.pid')

  def main_loop(self):
    log.debug("Main loop called")
    application = service.Application("skylived")
    SkylivedService = skylived.skylivedService('skylived', curdir=self.curdir)
    serviceCollection = service.IServiceCollection(application)
    SkylivedService.setServiceParent(serviceCollection)
    clientFactory = SkylivedService.getClientFactory()
    httpTunnel = SkylivedService.getHTTPTunnelServer()
    lx200Factory = SkylivedService.getLx200Factory()
    webguiResource = SkylivedService.getWebGui()
    pshellFactory = SkylivedService.getShellFactory()
    ircpwd = str(self.daemoncfg.get('ircbot', 'password'))
    ircnick = str(self.daemoncfg.get('ircbot', 'nickname'))
    ircchannels = str(self.daemoncfg.get('ircbot', 'channels'))
    ircFactory = SkylivedService.getIrcBot(ircnick, ircpwd, ircchannels)
    log.debug("Staring listeners")
    reactor.listenTCP(int(self.daemoncfg.get('chatserver', 'port')), clientFactory)
    privkey = self.daemoncfg.get('sslserver', 'privkey')
    cacert = self.daemoncfg.get('sslserver', 'cacert')
    sslContext = ssl.DefaultOpenSSLContextFactory(privkey, cacert)
    reactor.listenSSL(int(self.daemoncfg.get('sslserver', 'port')), clientFactory, contextFactory=sslContext)
    reactor.listenTCP(int(self.daemoncfg.get('lx200server', 'port')), lx200Factory)
    reactor.listenTCP(int(self.daemoncfg.get('webgui', 'port')), appserver.NevowSite(webguiResource))
    reactor.listenTCP(int(self.daemoncfg.get('httptunnel', 'port')), appserver.NevowSite(httpTunnel))
    if self.daemoncfg.get('ircbot', 'enable') == 'yes':
      reactor.connectTCP(str(self.daemoncfg.get('ircbot', 'server')), int(self.daemoncfg.get('ircbot', 'port')), ircFactory)
    if self.daemoncfg.get('pythonshell', 'enable') == 'yes':
       reactor.listenTCP(int(self.daemoncfg.get('pythonshell','port')), pshellFactory,
               interface=self.daemoncfg.get('pythonshell', 'listenip'))

    from skyliveDaemon.Database import dbschema
    dbservice = service.IService(dbschema.SkyliveStore)
    dbservice.setServiceParent(serviceCollection)
    dbservice.startService()
    SkylivedService.dbservice=dbservice

    log.debug("Running reactor")
    reactor.run()

if __name__ == "__main__":
   # Starting all loggers
   log = logging.getLogger( 'DaemonStarter' )
   log.addHandler(filedebug)
   log.setLevel( logging.INFO )
   SkylivedCore = logging.getLogger( 'SkylivedCore')
   SkylivedCore.setLevel( logging.DEBUG )
   SkylivedCore.addHandler( filedebug )
   Lx200Log = logging.getLogger( 'Lx200' )
   Lx200Log.setLevel( logging.DEBUG )
   Lx200Log.addHandler( filedebug )
   ClientsLog = logging.getLogger( 'Clients')
   ClientsLog.setLevel( logging.DEBUG )
   ClientsLog.addHandler( filedebug )
   WebGuiLog = logging.getLogger( 'Webgui')
   WebGuiLog.setLevel( logging.DEBUG )
   WebGuiLog.addHandler( filedebug )
   AuthLog = logging.getLogger('AuthLog')
   AuthLog.setLevel( logging.DEBUG )
   AuthLog.addHandler( filedebug )
   ObservLog = logging.getLogger('Observatory')
   ObservLog.setLevel( logging.DEBUG )
   ObservLog.addHandler( filedebug )
   IRCLog = logging.getLogger('IRCBot')
   IRCLog.setLevel( logging.DEBUG )
   IRCLog.addHandler( filedebug )
   HTTPTun = logging.getLogger('HTTPTunnel')
   HTTPTun.setLevel( logging.DEBUG )
   HTTPTun.addHandler( filedebug )
   EPHEMLog = logging.getLogger('EPHEM')
   EPHEMLog.setLevel( logging.DEBUG )
   EPHEMLog.addHandler( filedebug )
   DBLog = logging.getLogger('DBLog')
   DBLog.setLevel( logging.DEBUG )
   DBLog.addHandler( filedebug )
   logging.basicConfig()

   # staring the application
   log.debug("Starting daemon with option "+sys.argv[1]) 
   skylivedDaemon().process_command_line(sys.argv)
