#!/usr/bin/env python
"""TcEx App Init."""
# standard library
import argparse
import os
import sys
import traceback

# third-party
import colorama as c

# first-party
from tcex.bin import Init

# autoreset colorama
c.init(autoreset=True, strip=False)

epilog = (
    'The "tcinit" command it intended to enable quick development of ThreatConnect Exchange Apps.\n'
    '\nJob App Templates:\n'
    '  job              - This template provides the structure for a Job App without any App\n'
    '                     logic.\n'
    '  job_batch        - This template provides a working example of downloading remote threat \n'
    '                     intel (md5 hash indicators) and writing the data in the ThreatConnect \n'
    '                     Platform using the tcex batch module.\n'
    '\nPlaybook App Templates:\n'
    '  playbook         - This template provides the structure for a Playbook App without any\n'
    '                     App logic.\n'
    '  playbook_actions - This template provides an example of "actions" in a Playbook \n'
    '                     App. Using the "actions" feature a single Playbook App can have \n'
    '                     multiple actions to perform different operations on the provided data.\n'
    '  playbook_utility - This template provides a basic example of a utility App that takes \n'
    '                     an input, analyzes or modifies the data, and writes the results as \n'
    '                     output.\n'
    '\nExternal App Templates:\n'
    '  external         - This template provides the structure for a External App without any\n'
    '                     App logic.\n'
    '  external_ingress - This template provides a working example of downloading remote threat \n'
    '                     intel (md5 hash indicators) and writing the data in the ThreatConnect \n'
    '                     Platform using the tcex batch module.\n'
    '\nService App Templates:\n'
    '  service_api      - This template provides the structure for a API Service App.\n'
    '  service_trigger  - This template provides the structure for a Trigger Service App.\n'
    '  service_webhook  - This template provides the structure for a Webhook Trigger Service App.\n'
)

parser = argparse.ArgumentParser(
    epilog=epilog, formatter_class=argparse.RawDescriptionHelpFormatter
)
parser.add_argument('--branch', default='master', help='Git branch.')
parser.add_argument(
    '--layout', action='store_true', help='Create a layout.json file.', default=False,
)
parser.add_argument(
    '--migrate',
    action='store_true',
    help='Enable this flag to migrate an existing App.',
    default=False,
)
parser.add_argument(
    '--update',
    action='store_true',
    help='Enable this flag to update an existing App.',
    default=False,
)
parser.add_argument(
    '--template',
    choices=[
        'external',
        'external_ingress',
        'job',
        'job_batch',
        # 'job_enrichment',
        'playbook',
        'playbook_actions',
        # 'playbook_enrichment',
        'playbook_utility',
        'service_api',
        'service_trigger',
        'service_webhook',
    ],
    help='Choose an appropriate App template for the current project.',
)
args, extra_args = parser.parse_known_args()


if __name__ == '__main__':
    try:
        tci = Init(args)

        if not args.template and not os.listdir(os.getcwd()) and not args.update:
            tci.print_message(
                'The --template <template type> CLI arg is required when creating a new App. If '
                'trying to update an existing App please provide the --update CLI flag.',
                line_color=c.Fore.YELLOW,
            )
            sys.exit(1)
        elif not os.listdir(os.getcwd()) and args.update:
            tci.print_message(
                'The are no files to update. Try removing --update CLI flag.',
                line_color=c.Fore.YELLOW,
            )
            sys.exit(1)

        if os.listdir(os.getcwd()) and not args.update:
            tci.print_message(
                'The current directory does not appear to be empty. Please initialize the App in '
                'an empty directory. If migrating an older App try the --migrate CLI flag or if '
                'updating an App try the --update CLI flag.',
                line_color=c.Fore.YELLOW,
            )
            sys.exit(1)
        elif args.update and args.template is None and tci.tj.template is None:
            tci.print_message(
                'The template could not be determined. Please provide the template arg using '
                '--template <template name> to update template files.',
                line_color=c.Fore.YELLOW,
            )
            sys.exit(1)
        elif os.listdir(os.getcwd()) and not os.getenv('TCEX_DEVELOPER'):
            tci.print_message(
                'The current directory does not appear to be empty. Updating files can cause loss '
                'of data. It is STRONGLY recommend you commit/backup all your changes before '
                'proceeding. To disable this message set the TCEX_DEVELOPER environment variable '
                '(e.g. export TCEX_DEVELOPER=1).',
                line_color=c.Fore.YELLOW,
            )
            message = 'Continue (yes/[no]): '
            response = input(message).strip()  # nosec
            if response not in ['y', 'yes']:
                sys.exit()

        # use previous template value from tcex.json if template not passed
        template = args.template
        if template is None:
            template = tci.tj.template

        print(
            f'{c.Style.BRIGHT}Using files from {c.Fore.CYAN}"{args.branch}"{c.Fore.RESET} branch '
            f'and {c.Fore.CYAN}"{template}"{c.Fore.RESET} template.'
        )

        # download common files
        tci.download_template.init_common_files(template)

        # download type specific files
        if template.startswith('external'):
            tci.download_template.init_external(template)
        elif template.startswith('job'):
            tci.download_template.init_job()
        elif template.startswith('playbook'):
            tci.download_template.init_playbook()
        elif template.startswith('service'):
            tci.download_template.init_service(template)

        # if we are migrating, update the install.json
        if (args.update or args.migrate) and not template.startswith('external'):
            tci.ij.update(migrate=args.migrate)
            # APP-86 - sort output data by name
            if tci.lj.has_layout:
                tci.lj.update(features=tci.ij.features, prefix=tci.ij.output_prefix)

        # print results
        tci.download_template.print_download_results()

        # external and external_ingress templates do not use tcex.json or install.json
        if not template.startswith('external'):
            # update install.json
            tci.ij.update()

            # update tcex.json
            tci.tj.update(template)

        # provide helpful user info
        if not args.update:
            tci.print_message(
                'Please update displayName in install.json and package.app_name in tcex.json '
                'before packaging the App.',
                line_bright=True,
                line_color=c.Fore.GREEN,
            )

        # create layout.json file if requested
        if args.layout:
            tci.lj.create(tci.ij.params, tci.ij.output_variables)

        # cleanly exit
        sys.exit()

    except Exception:
        # TODO: Update this, possibly raise
        print(f'{c.Style.BRIGHT}{c.Fore.RED}{traceback.format_exc()}')
        sys.exit(1)
