# -*- coding: utf-8 -*-
# -----------------------------------------------------------------------------
# Copyright 2016 Continuum Analytics, Inc.
#
# All Rights Reserved.
# -----------------------------------------------------------------------------
import logging
import sys

import click

from anaconda_enterprise.cli import __version__
from anaconda_enterprise.cli.commands import (admin, channels, config_cmd,
                                              login, packages, pypi_index,
                                              spark_config, upload)
from anaconda_enterprise.cli.config import load_config
from anaconda_enterprise.cli.internal import stdin_is_interactive

program_name = 'anaconda-enterprise-cli'
slugified_program_name = program_name.replace('-', '_')
log = logging.getLogger(program_name)


# Click 7.0 introduced a breaking change that requires subcommands
# to use dashes instead of underscores. This provides back compatibility
# https://click.palletsprojects.com/en/7.x/upgrading/#upgrading-to-7-0
def normalize_command(name):
    return name.replace('_', '-')


group = click.Group(
    program_name, context_settings={'token_normalize_func': normalize_command})
click.version_option(__version__, prog_name=program_name)(group)
group.add_command(admin.main)
group.add_command(channels.main)
group.add_command(config_cmd.main)
group.add_command(login.main)
group.add_command(login.logout)
group.add_command(packages.main)
group.add_command(pypi_index.main)
group.add_command(upload.upload)
group.add_command(upload.upload_pypi)
group.add_command(spark_config.main)
group.add_command(spark_config.main, name='site-config')


@click.pass_context
def load_configuration_manager(context):
    config = load_config()
    context.obj = config


group.callback = load_configuration_manager


def main(argv=None):
    if argv is None:
        argv = sys.argv
    try:
        group.main(argv[1:], prog_name=program_name, standalone_mode=True)
    except (KeyboardInterrupt, click.Abort):
        sys.stderr.write('Aborted!')
        return 1
    except click.ClickException as exc:
        exc.show()
        return exc.exit_code
    except Exception:
        # Unexpected error
        (exception_type, exception_value, exception_trace) = sys.exc_info()

        try:
            import datetime
            import tempfile
            import traceback

            print("An unexpected error occurred, most likely a bug in %s." %
                  program_name,
                  file=sys.stderr)
            print("    (The error was: %s: %s)" %
                  (exception_type.__name__, str(exception_value)),
                  file=sys.stderr)

            # so batch jobs have the details in their logs
            output_to_console = not stdin_is_interactive()

            when = datetime.date.today().isoformat()
            prefix = "bug_details_%s_%s_" % (slugified_program_name, when)
            with tempfile.NamedTemporaryFile(prefix=prefix,
                                             suffix=".txt",
                                             delete=False) as bugfile:
                report_name = bugfile.name

                def output(s):
                    bugfile.write(s.encode('utf-8'))
                    bugfile.write("\n".encode('utf-8'))
                    if output_to_console:
                        print(s, file=sys.stderr)

                output("Bug details for %s error on %s" % (program_name, when))
                output("")
                output("sys.argv: %r" % sys.argv)
                output("")
                output("")
                output("\n".join(
                    traceback.format_exception(exception_type, exception_value,
                                               exception_trace)))

            if output_to_console:
                print("Above details were also saved to %s" % report_name,
                      file=sys.stderr)
            else:
                print("Details about the error were saved to %s" % report_name,
                      file=sys.stderr)
        except Exception:
            # re-raise the original exception, which is probably more useful
            # than reporting whatever was broken about our bug handling code
            # above.
            raise exception_value

        # exit code
        return 1


if __name__ == '__main__':
    sys.exit(main())
