#!/usr/bin/python3 -sP

import functools
import sys

import click

import tmt.cli
import tmt.utils

# A small helper for "print to sys.stderr".
print_error = functools.partial(print, file=sys.stderr)


def show_run_exception(exception: tmt.utils.RunError) -> None:
    """ Display detailed output upon command execution errors """

    # Check verbosity level used during raising exception,
    # Supported way to correctly get verbosity is
    # tmt.util.Common.opt('verbose')
    if isinstance(exception.caller, tmt.utils.Common):
        verbose = exception.caller.opt('verbose')
    else:
        verbose = 0
    for name, output in (('stdout', exception.stdout), ('stderr', exception.stderr)):
        if not output:
            continue
        lines = output.strip().split('\n')
        # Show all lines in verbose mode, limit to maximum otherwise
        if verbose > 0:
            line_summary = f"{len(lines)}"
        else:
            line_summary = f"{min(len(lines), tmt.utils.OUTPUT_LINES)}/{len(lines)}"
            lines = lines[-tmt.utils.OUTPUT_LINES:]
        print_error(
            f"{name} ({line_summary} lines)"
            f"\n{tmt.utils.OUTPUT_WIDTH * '~'}\n" +
            '\n'.join(lines) +
            f"\n{tmt.utils.OUTPUT_WIDTH * '~'}")
        print_error()


def show_exception(exception: BaseException) -> None:
    """ Display the exception and its causes """

    print_error()
    print_error(click.style(str(exception), fg='red'))

    if isinstance(exception, tmt.utils.RunError):
        print_error()
        show_run_exception(exception)

    # Follow the chain
    if exception.__cause__:
        print_error()
        print_error("The exception was caused by the previous exception:")

        show_exception(exception.__cause__)


try:
    tmt.cli.main()

# Basic error message for general errors
except tmt.utils.GeneralError as error:
    show_exception(error)
    raise SystemExit(2)
