import sys

import click

from common import config
from common.cli_utils import EnumChoice, configurable, error_reporting, versioned
from fest import UnsupportedError
from fest.heuristic import find_sym_model_by_heuristic
from fest.templates.stdlib.arith import TemplateChoice
from problems import Problem
from problems.cli_utils import problem_options


@click.command(
    help="Find and Evaluate Symbolic-structures via Templates",
    context_settings=dict(
        show_default=True,
        help_option_names=["-h", "--help"],
    ),
)
@versioned
@click.option("--quiet/--no-quiet", "-q/-Q", default=False)
@click.option(
    "--tstp",
    default=False,
    is_flag=True,
    help="Use TSTP (TPTP solution) output format; incompatible with quiet mode",
)
@click.option(
    "--template",
    "-t",
    type=EnumChoice(TemplateChoice),
    default=TemplateChoice.STANDARD,
)
@click.option(
    "--timeout",
    type=float,
    default=config.fest.timeout[float],
    help="Timeout (in seconds)",
)
@error_reporting
@configurable
@problem_options
def main(
    problems: set[Problem],
    quiet: bool,
    tstp: bool,
    template: TemplateChoice,
    timeout: float,
) -> None:
    assert not (quiet and tstp), "Quiet mode not compatible with TPTP output"
    failed = False
    with config.fest.timeout.override(timeout):
        for problem in problems:
            try:
                model = find_sym_model_by_heuristic(problem, template=template)
            except UnsupportedError as e:
                if quiet:
                    click.secho(".", fg="yellow", bold=True, nl=False)
                elif tstp:
                    click.echo(f"% SZS status Inappropriate for {problem.name}")
                else:
                    click.secho(f"{problem.name}: unsupported input, {e}", fg="yellow")
                continue

            if model is None:
                failed = True
                if quiet:
                    click.secho(".", fg="red", bold=True, nl=False)
                elif tstp:
                    click.echo(f"% SZS status GaveUp for {problem.name}")
                else:
                    click.secho(f"{problem.name}: no model found", fg="red")
            else:
                if quiet:
                    click.secho(".", fg="green", bold=True, nl=False)
                elif tstp:
                    click.echo(f"% SZS status Satisfiable for {problem.name}")
                    click.echo("% SZS output start Model")
                    print(model, end="")
                    click.echo("% SZS output end Model")
                else:
                    click.secho(problem.name, fg="green", bold=True, underline=True)
                    print(model, end="")

    if quiet:
        click.echo()

    if failed:
        sys.exit(-1)


if __name__ == "__main__":
    main()
