#!/usr/bin/python3
# -*- coding: utf-8 -*-

"""
This program mirrors bugs of specified projects from Bugzilla to Jira.
Forked from Christian Lanig <clanig@suse.com>

Author:                     Leon Schröder <lschroeder@suse.de>
Copyright:                  © 2020 SUSE Software Solutions Germany GmbH
SPDX-License-Identifier:    GPL-3.0-only
"""

import os
import sys
import logging
import time
import signal
import argparse
import importlib
from logging.handlers import SysLogHandler
from bugjira import config
from bugjira import updater
from bugjira.jiradata import Jiradata
from bugjira.bugzdata import Bugzdata
from bugjira.timestamp import Timestamp
from bugjira.patch import override_con_pool

SYSTEMD = importlib.util.find_spec("systemd")
if SYSTEMD:
    from systemd import journal

__author__ = 'Leon Schröder'
__copyright__ = '© 2020 SUSE Software Solutions Germany GmbH'
__license__ = 'GPL-3'
__version__ = '0.3'
__maintainer__ = 'Leon Schröder'
__email__ = 'lschroeder@suse.de'
__status__ = 'Beta'


def main():

    # cli parser init
    parser = argparse.ArgumentParser(description="Program to mirror " +
                                     "bug comments between Bugzilla and Jira.")
    parser.add_argument("-o", "--once", action="store_true",
                        dest="oneshot", help="just execute the mirroring "
                        + "function once and then exit")
    parser.add_argument("-d", "--debug", action="store_true",
                        help="debug mode")
    parser.add_argument("-f", "--full", action="store_true", dest="full",
                        help="ignores the timestamp and syncs all issues")
    parser.add_argument("-r", "--dry-run", action="store_true",
                        dest="dryrun",
                        help="just pretend to sync the comments to Jira")
    parser.add_argument("-v", "--version", action="version",
                        version=__version__, help="print version number")
    args = parser.parse_args()

    print("Initializing configuration")
    conf = config.Config()

    def signal_handler(sig, frame):
        print(' You asked bugjira to quit - goodbye!')
        os._exit(0)
    signal.signal(signal.SIGINT, signal_handler)

    # logger init
    log_lvl = logging.INFO
    if args.debug or (conf.VALUES["debug"] == "True"):
        log_lvl = logging.DEBUG
    log_fmt = "%(asctime)s %(levelname)-8s [%(filename)s:%(lineno)d] " + \
        "%(funcName)s: %(message)s"
    date_fmt = '%Y-%m-%d %H:%M:%S'
    logging.basicConfig(format=log_fmt, datefmt=date_fmt, level=log_lvl)
    logger = logging.getLogger(__package__)

    if SYSTEMD:
        logger.debug("Systemd found. Adding handler for system journal.")
        logger.addHandler(journal.JournalHandler())

    logger.addHandler(logging.handlers.SysLogHandler(address="/dev/log"))
    logger.debug("Configuration: %s", conf.VALUES)

    logger.debug("Overriding maximum number of connections with %s",
                 conf.VALUES["performance"]["max_connections"])
    override_con_pool(int(conf.VALUES["performance"]["max_connections"]))

    dryrun = False
    if (args.dryrun or conf.VALUES["dryrun"] == "True"):
        dryrun = True
    logger.debug("Dry-Run is set to: %s", dryrun)

    bugzdata = Bugzdata(conf)
    jiradata = Jiradata(conf)

    wait_secs = conf.VALUES["performance"]["wait_seconds"]
    safety_buf = float(conf.VALUES["performance"]["safety_buffer_secs"])
    stamp = Timestamp(0)
    if not args.full:
        stamp.load()
    else:
        stamp = ''

    while True:
        time_temp = Timestamp(safety_buf)
        direction = conf.VALUES["sync_to"]
        if not args.full:
            logger.info("Last sync %s UTC!", stamp)

        to_sync = updater.check_changes(bugzdata,
                                        jiradata,
                                        stamp,
                                        direction)
        if to_sync:
            logger.info("Issue update started...")
            updater.update_comments(bugzdata, jiradata, to_sync, dryrun)
            logger.info("Issue update finished.")

        else:
            logger.info("Nothing to do.")

        if args.oneshot:
            return True
        stamp = time_temp
        stamp.save()

        logger.debug("Waiting for %s seconds.", wait_secs)
        time.sleep(float(wait_secs))


if __name__ == "__main__":
    main()
