#!python

import os
import logging
import traceback
from sys import argv
from datetime import datetime

from dynamite_nsm import const
from dynamite_nsm import updater
from dynamite_nsm import utilities
from dynamite_nsm.logger import get_logger
from dynamite_nsm.commandline import component_args
from dynamite_nsm.commandline import component_parsers
from dynamite_nsm.components.lab.component import LabCommandlineComponent
from dynamite_nsm.components.agent.component import AgentCommandlineComponent
from dynamite_nsm.components.kibana.component import KibanaCommandlineComponent
from dynamite_nsm.components.monitor.component import MonitorCommandlineComponent
from dynamite_nsm.components.updates.component import UpdatesCommandlineComponent
from dynamite_nsm.components.logstash.component import LogstashCommandlineComponent
from dynamite_nsm.components.dynamited.component import DynamitedCommandlineComponent
from dynamite_nsm.components.elasticsearch.component import ElasticsearchCommandlineComponent

component_args.register_agent_component_args(
    component_parsers.agent_component_parser, parent_parsers=[component_parsers.base_parser]
)
component_args.register_elasticsearch_component_args(
    component_parsers.elasticsearch_component_parser, parent_parsers=[component_parsers.base_parser]
)
component_args.register_logstash_component_args(
    component_parsers.logstash_component_parser, parent_parsers=[component_parsers.base_parser]
)
component_args.register_kibana_component_args(
    component_parsers.kibana_component_parser, parent_parsers=[component_parsers.base_parser]
)
component_args.register_monitor_component_args(
    component_parsers.monitor_component_parser, parent_parsers=[component_parsers.base_parser]
)
component_args.register_lab_component_args(
    component_parsers.lab_component_parser, parent_parsers=[component_parsers.base_parser]
)
component_args.register_dynamited_component_args(
    component_parsers.dynamited_component_parser, parent_parsers=[component_parsers.base_parser]
)
component_args.register_updates_component_args(
    component_parsers.update_component_parser, parent_parsers=[component_parsers.base_parser]
)

if __name__ == '__main__':
    if not utilities.is_root():
        from sys import stderr
        stderr.write('\033[91m[-] This script must be run as \033[4mroot\033[0m.\033[0m\n')
        exit(1)
    if len(argv) < 2:
        component_parsers.main_parser.print_help()
        exit(1)
    if argv[1] in ["-v", "--version"]:
        utilities.print_dynamite_logo(const.VERSION)
        exit(0)

    utilities.create_dynamite_environment_file()
    args = component_parsers.main_parser.parse_args()
    today_formatted_date = datetime.strftime(datetime.today(), '%d-%m-%Y')
    log_level = logging.INFO
    try:
        if args.verbose:
            log_level = logging.DEBUG
    except AttributeError:
        log_level = logging.INFO
    logger = get_logger('DYNAMITE_CMD', level=log_level, stdout=True)
    logger.info("LOG LEVEL: {}".format(log_level))
    logger.info("LOG FILE: {}.log".format(os.path.join(const.LOG_PATH, 'dynamite-{}'.format(today_formatted_date))))
    if 'action_name' not in args:
        component_parsers.main_parser.print_help()
        component_parsers.main_parser.error(
            "Missing {} 'action' (E.G install, uninstall, start, stop, restart, status)".format(args.component_name))
    if args.component_name:
        if not os.path.exists(const.MIRRORS):
            logger.info('Updating mirrors...please wait.')
            updater.update_mirrors()
            logger.info('Mirror update complete.')
        if not os.path.exists(const.DEFAULT_CONFIGS):
            logger.info('Updating templates...please wait.')
            updater.update_default_configurations()
            logger.info('Template update complete. Please re-run: {}'.format(' '.join(argv)))
            exit(0)

    try:
        if args.component_name == "agent":
            AgentCommandlineComponent(args)
        elif args.component_name == "elasticsearch":
            ElasticsearchCommandlineComponent(args)
        elif args.component_name == "logstash":
            LogstashCommandlineComponent(args)
        elif args.component_name == "kibana":
            KibanaCommandlineComponent(args)
        elif args.component_name == "monitor":
            MonitorCommandlineComponent(args)
        elif args.component_name == "lab":
            LabCommandlineComponent(args)
        elif args.component_name == "daemon":
            DynamitedCommandlineComponent(args)
        elif args.component_name == "updates":
            UpdatesCommandlineComponent(args)
    except KeyboardInterrupt:
        print("\n[+] Exiting")
        exit(0)
    except Exception as e:
        if log_level != logging.DEBUG:
            logger.critical("Fatal error. Add --verbose flag for details. Exiting.")
        else:
            logger.critical("Fatal error. Exiting.")
        logger.debug("Fatal error. Exiting; {}".format(e))
        if log_level == logging.DEBUG:
            traceback.print_exc(limit=15)
