#!/usr/bin/python3
# -*- coding: utf8 -*-


import configparser
import xivo_dao

from twisted.python import usage
from twisted.internet import reactor
from twisted.application import service, internet

from xivo_confgen.confgen import ConfgendFactory


class Options(usage.Options):
    optParameters = [
        ['listen'   , 'l', '*' , 'listen interface (* = all)', str],
        ['port'     , 'p', 5035, 'confgend server port'      , int],
        ['cache'    , 'a', '/var/lib/xivo-confgend', 'config cache', str],
        ['conf'     , 'c', '/etc/xivo/xivo-confgend.conf', 'Configuration file', str],
        ['db_uri'   , 'd', 'postgresql://asterisk:proformatique@localhost/asterisk', 'DB URI', str],
        ['log_filename', 'logfile', '/var/log/xivo-confgend.log', 'log file', str],
        ['debug', 'debug', 'False', 'debug enabled', bool],
        ['foreground', 'f', 'False', 'foreground', bool],
        ['log_level', 'loglevel', 'info', 'log level', str]
    ]


options = Options()
if __name__ == '__main__':
    """

        NOTE: commandline options overrides config file values
    """
    options.parseOptions()

config = configparser.RawConfigParser()
config.read(options['conf'])

for key, value in config.items('confgend'):
    if key not in options.defaults:
        raise Exception("Unknown '%s' key in %s configuration file" % (key, options['conf']))

    # coerce value
    if key in options._dispatch:
        # NOTE: cannot directly use CoerceParameter.dispatch() as it affect result to opts dict
        try:
            value = options._dispatch[key].coerce(value)
        except ValueError as e:
            raise Exception("*%s* key in *%s* configuration file is invalid type" % (key, options['conf']))

    # replace if not set inline
    if options[key] == options.defaults[key]:
        options[key] = value

if options['listen'] == '*':
    options['listen'] = ''

xivo_dao.init_db(options['db_uri'])

f = ConfgendFactory(options['cache'], config, options)

if __name__ == '__main__':
    reactor.listenTCP(options['port'], f, interface=options['listen'])
    reactor.run()

application = service.Application('confgend')
service.IProcess(application).processName = "confgend"

svc = internet.TCPServer(options['port'], f, interface=options['listen'])
svc.setServiceParent(application)
