#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""TcEx App Init."""
import argparse
import sys
import traceback

import colorama as c
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(
    '--action',
    choices=['create', 'update', 'migrate'],
    default='create',
    help=(
        '(default: create) Choose "create" to initialize a new App, "update" to download updates '
        'to App framework files, and "migrate" to update a non App Builder compliant App to use a '
        'standard template.'
    ),
)
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.',
)
parser.add_argument(
    '--force',
    action='store_true',
    help='Enable this flag to forcibly overwrite existing files in the current working directory.',
    default=False,
)
args, extra_args = parser.parse_known_args()


if __name__ == '__main__':
    try:
        tci = Init(args)
        print(f'{c.Style.BRIGHT}{c.Fore.WHITE}Using files from "{args.branch}" branch')

        if args.action == 'update' or args.action == 'migrate':
            # check if the current directory is empty
            tci.check_empty_app_dir()

        # create a new app OR migrate an app of a different form to the new app format
        if args.action == 'create' or args.action == 'migrate':

            # TODO: in updated command tool this should not be a default.
            template = tci.args.template
            if template is None:
                template = 'playbook'
                print(f'{c.Fore.YELLOW}No template provided, defaulting to {template}.')

            # download common files
            tci.download_file('.pre-commit-config.yaml')
            tci.download_file('coveragerc', '.coveragerc')
            tci.download_file('gitignore', '.gitignore')
            tci.download_file('pyproject.toml')
            tci.download_file('README.md')
            tci.download_file('requirements.txt')
            tci.download_file('setup.cfg')

            # download type specific files
            if template.startswith('external'):
                tci.download_file('external/external_app.py', 'external_app.py')
                tci.download_file('external/run.py', 'run.py')
            elif template.startswith('job'):
                tci.download_file('__main__.py')
                tci.download_file('job/job_app.py', 'job_app.py')
                tci.download_file('job/run.py', 'run.py')
            elif template.startswith('playbook'):
                tci.download_file('__main__.py')
                tci.download_file('playbook/playbook_app.py', 'playbook_app.py')
                tci.download_file('playbook/run.py', 'run.py')
            elif template.startswith('service'):
                tci.download_file('app_lib.py')
                tci.download_file('service/service_app.py', 'service_app.py')
                tci.download_file(f'{template}/run.py', 'run.py')

            # download template specific files
            tci.download_file(f'{template}/app.py', 'app.py')
            if template.startswith('external'):
                tci.download_file(f'{template}/app_config.json', 'app_config.json')
            else:
                tci.download_file(f'{template}/args.py', 'args.py')
                tci.download_file(f'{template}/install.json', 'install.json')
                tci.download_file(f'{template}/tcex.json', 'tcex.json')

            # if we are migrating, update the install.json
            if not template.startswith('external') and args.action == 'migrate':
                tci.update_install_json()

        elif args.action == 'update':
            template_map = {
                'organization': 'job',
                'playbook': 'playbook',
                'apiservice': 'service_api',
                'triggerservice': 'service_trigger',
                'webhooktriggerservice': 'service_webhook',
            }
            # TODO: test on external App
            template = tci.args.template
            if template is None:
                template = template_map.get(tci.ij.runtime_level.lower(), 'external')
                print(f'{c.Fore.CYAN}Using template "{template}" for updates.')

            # update common files
            tci.download_file('.pre-commit-config.yaml')
            tci.download_file('gitignore', '.gitignore')
            tci.download_file('pyproject.toml')
            tci.download_file('README.md')
            tci.download_file('requirements.txt')
            tci.download_file('setup.cfg')

            # update type specific files
            if template.startswith('external'):
                tci.download_file('external/external_app.py', 'external_app.py')
                tci.download_file('external/run.py', 'run.py')
            elif template.startswith('job'):
                tci.download_file('__main__.py')
                tci.download_file('job/job_app.py', 'job_app.py')
                tci.download_file('job/run.py', 'run.py')
            elif template.startswith('playbook'):
                tci.download_file('__main__.py')
                tci.download_file('playbook/playbook_app.py', 'playbook_app.py')
                tci.download_file('playbook/run.py', 'run.py')
            elif template.startswith('service'):
                tci.download_file('app_lib.py')
                tci.download_file(f'{template}/run.py', 'run.py')
                tci.download_file('service/service_app.py', 'service_app.py')

            # update tcex.json file
            tci.update_tcex_json()
        sys.exit()

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