"""The ZnTrack CLI."""
import importlib.metadata
import pathlib
import sys
import uuid

import typer

from zntrack import Node, utils

app = typer.Typer()


def version_callback(value: bool) -> None:
    """Get the installed 'ZnTrack' version."""
    if value:
        typer.echo(f"ZnTrack {importlib.metadata.version('zntrack')}")
        raise typer.Exit()


@app.callback()
def main(
    version: bool = typer.Option(
        None, "--version", callback=version_callback, is_eager=True
    ),
) -> None:
    """ZnTrack CLI main callback."""
    _ = version  # this would be greyed out otherwise


@app.command()
def run(node: str, name: str = None, hash_only: bool = False) -> None:
    """Execute a ZnTrack Node.

    Use as 'zntrack run module.Node --name node_name'.
    """
    sys.path.append(pathlib.Path.cwd().as_posix())

    package_and_module, cls = node.rsplit(".", 1)
    module = importlib.import_module(package_and_module)

    cls = getattr(module, cls)

    if getattr(cls, "is_node", False):
        cls(exec_func=True)
    elif issubclass(cls, Node):
        node: Node = cls.from_rev(name=name)
        if hash_only:
            (node.nwd / "hash").write_text(str(uuid.uuid4))
        else:
            node.run()
            node.save(parameter=False)
    else:
        raise ValueError(f"Node {node} is not a ZnTrack Node.")


@app.command()
def init(
    name: str = "New Project",
    gitignore: bool = typer.Option(
        False, help="Create a gitignore file with all the usual files excluded."
    ),
    force: bool = typer.Option(
        False, "--force", "-f", help="Initialize Project if the directory is not empty."
    ),
):
    """Initialize a new ZnTrack Project."""
    initializer = utils.cli.Initializer(name=name, gitignore=gitignore, force=force)
    initializer.run()
