__all__ = [
    "validate",
    "mecha",
    "main",
]


import logging
import zipfile
from pathlib import Path
from typing import Tuple

import click
from beet import Context, DataPack, Function, run_beet
from beet.toolchain.cli import BeetCommand, LogHandler, error_handler, message_fence

from mecha import __version__

from .api import Mecha


def validate(ctx: Context):
    """Plugin for running mecha on the provided sources."""
    mc = ctx.inject(Mecha)
    source = ctx.meta["source"]

    for path in map(Path, source):
        if zipfile.is_zipfile(path) or (path / "data").is_dir():
            mc.compile(DataPack(path=path), report=mc.diagnostics)
        elif path.is_dir():
            for filename in path.glob("**/*.mcfunction"):
                mc.compile(Function(source_path=filename), report=mc.diagnostics)
        elif path.is_file():
            mc.compile(Function(source_path=path), report=mc.diagnostics)


@click.command(
    cls=BeetCommand,
    context_settings={"help_option_names": ("-h", "--help")},
)
@click.argument("source", nargs=-1, type=click.Path(exists=True))
@click.option(
    "-m",
    "--minecraft",
    metavar="VERSION",
    default="1.17",
    help="Minecraft version.",
)
@click.option(
    "-l",
    "--log",
    metavar="LEVEL",
    type=click.Choice(
        ["CRITICAL", "ERROR", "WARNING", "INFO", "DEBUG"],
        case_sensitive=False,
    ),
    default="WARNING",
    help="Configure output verbosity.",
)
@click.version_option(
    __version__,
    "-v",
    "--version",
    message=click.style("%(prog)s", fg="red")
    + click.style(" v%(version)s", fg="green"),
)
@error_handler(should_exit=True)
def mecha(source: Tuple[str, ...], minecraft: str, log: str):
    """Validate data packs and .mcfunction files."""
    logger = logging.getLogger()
    logger.setLevel(log)
    logger.addHandler(LogHandler())

    config = {
        "pipeline": ["mecha.cli.validate"],
        "meta": {
            "source": source,
            "mecha": {
                "version": minecraft,
                "readonly": True,
            },
        },
    }

    with message_fence(f"Validating with mecha v{__version__}"):
        if source:
            with run_beet(config):
                pass
        else:
            logger.warning("No path provided.", extra={"prefix": "mecha"})
            logger.warning("Use --help to see usage.", extra={"prefix": "mecha"})


def main():
    """Invoke the command-line entrypoint."""
    mecha(prog_name="mecha")
