from __future__ import annotations

import subprocess

import click

from pycage import clean
from pycage.helpers import get_interpreter, print_error


@click.command(help="precompile all Python files in the standalone distribution")
@click.option(
    "-q",
    "--quiet",
    is_flag=True,
    default=False,
    show_default=True,
    help=("do not list compiling files during procedure"),
)
@click.option(
    "-d",
    "--delete-existing",
    is_flag=True,
    default=False,
    show_default=True,
    help=("delete other pre-compiled files before compilation"),
)
@click.option(
    "-f",
    "--force",
    is_flag=True,
    default=False,
    show_default=True,
    help=(
        "force re-compilation of files even if the "
        "timestamps suggest that they did not change"
    ),
)
@click.option(
    "-o",
    "--optimise",
    type=click.IntRange(min=0, max=2),
    default=0,
    show_default=True,
    help=(
        "decide if optimisation should be applied. Following values are allowed: "
        "0: no optimisation, 1: remove asserts, 2: also remove docstrings"
    ),
)
def compile(
    optimise: int,
    force: bool,
    delete_existing: bool,
    quiet: bool,
) -> None:
    try:
        pth_intp = get_interpreter()
    except RuntimeError:
        click.echo("Base interpreter path could not be found", err=True)
        return

    if delete_existing:
        try:
            clean.delete_files(r"**/*.pyc")
        except Exception as err:
            print_error(err)
            return

    opt_level: str = ""
    if optimise == 1:
        opt_level = "-O"
    elif optimise == 2:
        opt_level = "-OO"

    quiet_opt: str = ""
    if quiet:
        quiet_opt = "-q"

    exclude_rx: str = "[\\\\|/]+tcl[\\\\|/]+"
    run_cmd: list[str] = [
        str(pth_intp),
        opt_level,
        "-m",
        "compileall",
        "./python/",
        "-x",
        exclude_rx,
        "-o",
        str(optimise),
        quiet_opt,
    ]
    if force:
        run_cmd.extend(("-f",))

    run_cmd = [cmd for cmd in run_cmd if cmd]

    try:
        subprocess.run(run_cmd)
    except Exception as err:
        print_error(err)
        return

    click.echo("The compilation process was successful.")
