"""
koci - Universal CI Definition Tool

Run CI pipelines locally and export to any CI platform.
"""

from cement import App, TestApp, init_defaults
from cement.core.exc import CaughtSignal

from .core.exc import KociError
from .controllers.base import Base
from .controllers.run import Run
from .controllers.validate import Validate
from .controllers.init import Init
from .controllers.export import Export
from .controllers.watch import Watch
from .controllers.visualize import Visualize

# Configuration defaults
CONFIG = init_defaults('koci')
CONFIG['koci']['debug'] = False


class Koci(App):
    """KoCi primary application."""

    class Meta:
        label = 'koci'

        # Configuration defaults
        config_defaults = CONFIG

        # Call sys.exit() on close
        exit_on_close = True

        # Load additional framework extensions
        extensions = [
            'yaml',
            'colorlog',
            'jinja2',
        ]

        # Configuration handler
        config_handler = 'yaml'

        # Configuration file suffix
        config_file_suffix = '.yml'

        # Set the log handler
        log_handler = 'colorlog'

        # Set the output handler
        output_handler = 'jinja2'

        # Register handlers (controllers)
        handlers = [
            Base,
            Run,
            Validate,
            Init,
            Export,
            Watch,
            Visualize,
        ]


class KociTest(TestApp, Koci):
    """A sub-class of Koci that is better suited for testing."""

    class Meta:
        label = 'koci'


def main():
    with Koci() as app:
        try:
            app.run()

        except AssertionError as e:
            print('AssertionError > %s' % e.args[0])
            app.exit_code = 1

            if app.debug is True:
                import traceback
                traceback.print_exc()

        except KociError as e:
            print('KociError > %s' % e.args[0])
            app.exit_code = 1

            if app.debug is True:
                import traceback
                traceback.print_exc()

        except CaughtSignal as e:
            # Default Cement signals are SIGINT and SIGTERM, exit 0 (non-error)
            print('\n%s' % e)
            app.exit_code = 0


if __name__ == '__main__':
    main()
