#!/usr/bin/env python

import argparse
import logging
import logging.handlers
import rss2jira
import sys
import yaml
from rss2jira import Sqlite3TrackedEntries, BindingFactory, RssReader, MainLoop
from rss2jira import JiraWrapper



class StreamToLogger(object):
    """
    Fake file-like stream object that redirects writes to a logger instance.
    From: http://www.electricmonk.nl/log/2011/08/14/redirect-stdout-and-stderr-to-a-logger-in-python/
    nnutter: Modified original to handle buffers not terminating in newlines.
    """
    def __init__(self, logger, log_level=logging.INFO):
        self.logger = logger
        self.log_level = log_level
        self.linebuf = ''
        self.buf = ''

    def write(self, buf):
        lines = buf.splitlines(True)

        # Need to detect other types of newlines... universal newlines?
        if lines[-1][-1] != '\n':
            self.buf += lines.pop()

        for i in range(len(lines)):
            if self.buf:
                self.logger.log(self.log_level, self.buf + lines[i].rstrip())
                self.buf = ''
            else:
                self.logger.log(self.log_level, lines[i].rstrip())


def parse_args():
    parser = argparse.ArgumentParser(prog='rss2jira')
    parser.add_argument('-c', '--config', default='rss2jira.conf',
            help='config file')
    parser.add_argument('-s', '--sleep', default=900, type=int,
            help='sleep duration between RSS fetches (seconds)')
    parser.add_argument('-d', '--debug', action='store_true',
            help='enable debug messages')
    parser.add_argument('-r', '--reset-db', action='store_true',
            help='reset the database')
    parser.add_argument('-l', '--log', help='log file')
    parser.add_argument('--daemon', action='store_true',
            help='enable daemon mode')
    return parser.parse_args()

def configure_logging(args):
    logger = logging.getLogger()
    formatter = logging.Formatter('%(asctime)-15s - %(name)s - %(levelname)s - %(message)s')

    if args.log:
        if args.daemon:
            fh = logging.FileHandler(args.log)
        else:
            fh = logging.handlers.TimedRotatingFileHandler(args.log, backupCount=5, when='d', interval=7)
        fh.setFormatter(formatter)
        logger.addHandler(fh)

    if args.daemon:
        sys.stdout = StreamToLogger(logger, logging.INFO)
        sys.stderr = StreamToLogger(logger, logging.ERROR)
    else:
        ch = logging.StreamHandler()
        ch.setFormatter(formatter)
        logger.addHandler(ch)

    if args.debug:
        logger.setLevel(logging.DEBUG)
        logging.debug('Logging level set to debug.')
    else:
        logger.setLevel(logging.INFO)
        logging.info('Logging level set to info.')

    if args.daemon:
        logging.captureWarnings(True)

def main():
    args = parse_args()
    configure_logging(args)

    app_config = yaml.load(open(args.config))
    storage = Sqlite3TrackedEntries(app_config['db_path'])
    if args.reset_db:
        storage.clear()

    binding_factory = BindingFactory(app_config, storage, RssReader,
            JiraWrapper)

    main_loop = MainLoop(app_config, binding_factory, args.sleep,
            stop_condition=lambda: False)
    main_loop.run()

if __name__ == "__main__":
    main()
