#!/usr/bin/python2.7 -tt

__version__ = "0.6/TCPCONNECT"
__default_config__ = "./examples/minimal.json"

import argparse
import logging
import logging.handlers
import os
import os.path as path
from apscheduler.scheduler import Scheduler
from lib.config.parser import FullConfigParser
from lib.core.job import Job
from lib.frontends.lish import LishFrontend


def parseArgs():
    parser = argparse.ArgumentParser(
        description="Linspector is for monitoring the vital information of hosts, services and devices in a network.",
        epilog="linspector is not some program expecting computers to run! Visit http://linspector.org for more "
               "information.",
        prog="linspector")

    parser.add_argument("--version", action="version", version="%(prog)s " + str(__version__))
    #TODO: make the config file a required field without -c or --config at the end eg: linspector config.json
    parser.add_argument("-c", "--config", default=__default_config__,
                        help="select configfile to use")
    parser.add_argument("-l", "--logfile", default="./log/linspector.log", metavar="FILE",
                        help="set logfile to use")

    output = parser.add_mutually_exclusive_group()
    output.add_argument("-q", "--quiet", action="store_const", dest="loglevel", const=logging.ERROR,
                        help="output only errors")
    output.add_argument("-w", "--warning", action="store_const", dest="loglevel", const=logging.WARNING,
                        help="output warnings")
    output.add_argument("-v", "--verbose", action="store_const", dest="loglevel", const=logging.INFO,
                        help="output info messages")
    output.add_argument("-d", "--debug", action="store_const", dest="loglevel", const=logging.DEBUG,
                        help="output debug messages")
    output.set_defaults(loglevel=logging.INFO)
    return parser.parse_args()


def setupLogging(logfile="./log/linspector.log", logLevel=logging.DEBUG, logfileLevel=logging.DEBUG):
    logfile = path.expanduser(logfile)
    if not path.exists(path.dirname(logfile)):
        os.makedirs(path.dirname(logfile))

    log = logging.getLogger("LinspectorLogger")
    log.setLevel(logging.DEBUG)

    consoleHandler = logging.StreamHandler()
    consoleHandler.setLevel(logLevel)

    fileHandler = logging.handlers.RotatingFileHandler(logfile, maxBytes=1024000, backupCount=4)
    fileHandler.setLevel(logfileLevel)

    consoleFormatter = logging.Formatter('[%(levelname)s]: %(message)s')
    #TODO: if debug with file and function else without that
    fileFormatter = logging.Formatter('%(asctime)s %(pathname)s %(module)s %(funcName)s %(lineno)d [%(levelname)s]: %(message)s')

    consoleHandler.setFormatter(consoleFormatter)
    fileHandler.setFormatter(fileFormatter)

    log.addHandler(consoleHandler)
    log.addHandler(fileHandler)
    return log


def handleJob(jobInfo):
    jobInfo.handle_call()


def main():
    args = parseArgs()
    #TODO: catch all log messages (apscheduler etc.); make logging more generic to support libraries logging
    log = setupLogging(args.logfile, args.loglevel)

    log.info("parsed arguments")

    configParser = FullConfigParser(log)
    linConf, core = configParser.parse_config(args.config)

    scheduler = Scheduler()

    scheduler.start()
    jobs = []

    for layout in linConf.get_enabled_layouts():
        for hostgroup in layout.get_hostgroups():
            for service in hostgroup.get_services():
                for host in hostgroup.get_hosts():
                    for period in service.get_periods():
                        job = Job(service, host, hostgroup.get_members(), hostgroup.get_processors(), core)
                        schedulerJob = period.createJob(scheduler, job, handleJob)
                        if schedulerJob is not None:
                            job.set_job(schedulerJob)
                            job.set_logger(log)
                            jobs.append(job)

    frontend = LishFrontend(jobs=jobs, scheduler=scheduler, linspectorConfig=linConf)

    log.debug("shutting down scheduler")
    logging.shutdown()
    scheduler.shutdown(wait=True)


if __name__ == "__main__":
    main()