#!/usr/bin/env python
""" Main module of replayer.
"""

import argparse
import Queue
import logging
import signal
import sys
import os.path

import apachelog

import replayer
from replayer.config_reader import ConfigReader
from replayer.http_worker import HTTPWorker
from replayer.url_filter import URLFilter
from replayer.url_builder import URLBuilder
from replayer.config_constants import ConfigConstants
from replayer.inspector import Inspector





# global variables
thread_list = []
killed = False

# signal handler to handle ctrl-c
def signal_handler(signal, frame):
    global killed
    killed = True
    for t in thread_list:
        t.kill()


def print_infos(logfile):
    logging.info('This is replayer, Version ' + replayer.__version__)
    logging.info('Copyright 2014 Andreas Buechele, https://github.com/buechele/replayer')
    logging.info('replayer is released under the terms of the MIT license.')
    logging.info('')
    logging.info('Replaying ' + logfile + ' (be patient)...')
    logging.info('')


def print_results(config, inspector):
    logging.info('')
    logging.info('Host:\t\t\t' + config[ConfigConstants.HOST])
    logging.info('')
    logging.info(inspector)


def main():
    # register signal handler
    signal.signal(signal.SIGINT, signal_handler)

    # parse command line args
    parser = argparse.ArgumentParser(description='Replay an Apache access-log.')
    parser.add_argument('-f', dest=ConfigConstants.LOGFILE, help='Apache access.log', required=True)
    parser.add_argument('-c', dest=ConfigConstants.CONFIGFILE, help='Configuration file to use', required=False)
    parser.add_argument('-n', dest=ConfigConstants.THREADCOUNT, type=int, help='Concurrency level', default=1,
                        required=False)
    parser.add_argument('-v', dest=ConfigConstants.VERBOSE, help='Increase output verbosity', action='store_true',
                        required=False)
    args = vars(parser.parse_args())

    # read config file
    config_reader = ConfigReader(args[ConfigConstants.CONFIGFILE])
    config_reader.merge_dict(args)
    config = config_reader.get_config()

    # configure logging
    logging.getLogger('requests').setLevel(logging.WARNING)
    if config[ConfigConstants.VERBOSE]:
        logging.basicConfig(level=logging.DEBUG, format='%(message)s')
    else:
        logging.basicConfig(level=logging.INFO, format='%(message)s')

    # check if access log exists
    if not os.path.isfile(config[ConfigConstants.LOGFILE]):
        logging.error('log file ' + config[ConfigConstants.LOGFILE] + ' does not exist!')
        sys.exit(1)

    # check if host is configured
    if not config[ConfigConstants.HOST]:
        logging.error('Host is not configured!')
        sys.exit(1)

    # initialize worker objects
    parser = apachelog.parser(config[ConfigConstants.LOGFORMAT])
    url_queue = Queue.Queue(config[ConfigConstants.THREADCOUNT] * 10)
    url_builder = URLBuilder("http", config[ConfigConstants.HOST], 80, config[ConfigConstants.TRANSFORM])
    if config.has_key(ConfigConstants.FILTER):
        url_filter = URLFilter(config[ConfigConstants.FILTER], config[ConfigConstants.FILTERRULE])
    else:
        url_filter = URLFilter({})

    # general information
    print_infos(config[ConfigConstants.LOGFILE])

    # init and start threads
    for i in range(config[ConfigConstants.THREADCOUNT]):
        t = HTTPWorker(i + 1, config[ConfigConstants.HEADER], url_queue, url_filter, url_builder)
        thread_list.append(t)
        t.start()

    # read access log
    for line in open(config[ConfigConstants.LOGFILE]):
        try:
            data = parser.parse(line)
            url_queue.put(data, True)
            if killed:
                break
        except:
            logging.error('Unable to parse %s' % line)

    inspector = Inspector()

    # close threads
    for t in thread_list:
        t.stop()
        t.join()
        inspector += t.get_inspector()

    # print results
    print_results(config, inspector)


if __name__ == '__main__':
    main()