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

import ConfigParser
import os.path
import sys
from twisted.python             import usage
from twisted.internet           import reactor
from twisted.internet.protocol  import Protocol, ClientFactory


class ConfigGetter(Protocol):
    def connectionMade(self):
        self.transport.write(self.factory.key)

    def dataReceived(self, data):
        sys.stdout.write(data)


class ConfigGetterFactory(ClientFactory):
    protocol = ConfigGetter

    def __init__(self, key):
        self.key = key
        self.exit_status = 0

    def clientConnectionFailed(self, connector, reason):
        self.exit_status = 1
        reactor.stop()

    def clientConnectionLost(self, connector, reason):
        reactor.stop()


class Options(usage.Options):
    optParameters = [
            ['server' , 's', 'localhost', 'confgend server host/ip', str],
            ['port'   , 'p', 5035       , 'confgend server port', int],
            ['timeout', 't', 5          , 'connexion timeout', int],
            ['conf'   , 'c', '/etc/pf-xivo/xivo-confgen.conf', 'Configuration file', str],
    ]

    def parseArgs(self, confkey):
        self['confkey'] = confkey

    def getSynopsis(self):
        return "Usage: %s [options] frontend/conffile" % os.path.basename(sys.argv[0])


def main():
    o = Options()
    try:
        o.parseOptions()
    except usage.UsageError:
        print o
        sys.exit(1)

    config = ConfigParser.RawConfigParser()
    config.read(o['conf'])
    for key, value in config.items('confgen'):
        if key not in o.defaults:
            raise Exception("Unknown '%s' key in %s configuration file" % (key, o['conf']))

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

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

    factory = ConfigGetterFactory(o['confkey'])
    reactor.connectTCP(o['server'], o['port'], factory, timeout=o['timeout'])
    reactor.run()

    sys.exit(factory.exit_status)


if __name__ == '__main__':
    main()
