#!/usr/bin/python
#
# Apply changes defined in a configuration file

import sys
import traceback

from modipy.options import ChangeOptions
from modipy.confloader import ConfigLoader, ChangeController
from twisted.internet import reactor
from twisted.python import log as tlog

import logging
log = logging.getLogger('modipy')

usage = "modipy [options] [ <device> ... ]"

optparser = ChangeOptions(usage=usage)
optparser.parseOptions()

# Cobble together a return code because reactor.stop()
# doesn't really support one.
EXITVAL=0

def mystop( (successes, failures) ):
    log.debug("finished: %d successes, %d failures" % (successes, failures) )
    global EXITVAL
    EXITVAL=failures

    reactor.stop()
    pass

def errstop(failure):
    log.error("Changes not implemented ok!")
    tlog.err(failure)
    global EXITVAL
    EXITVAL=-1
    reactor.stop()

def go():

    cfgldr = ConfigLoader()

    d = cfgldr.load_config(optparser.options, optparser.args)
    def config_loaded(ignored, cfgldr):
        log.debug("changes to apply: %s", cfgldr.changes)
        log.debug("total devices: %s", cfgldr.devices)

    d.addCallback(config_loaded, cfgldr)
    
    controller = ChangeController(cfgldr)

    if getattr(optparser.options, 'loadonly', False):
        log.info("Load only specified")
        reactor.callLater(0, mystop, (0,0))
        return

    d.addCallback(controller.do_changes)
    d.addCallbacks(mystop, errstop)

# Use callLater(0) syntax to trigger running of changes once
# the reactor has actually started, so it can be stopped cleanly.
reactor.callLater(0, go)
reactor.run()

# Exit with the number of failures, or -1 if an uncaught error happened.
sys.exit(EXITVAL)
