import argparse
from pathlib import Path
import sys

from dep_orbits import node
from dep_orbits.parse import NoDependenciesException, calculate_tree
from dep_orbits.server import start_server
from dep_orbits.utils import find_root, identify_path

RESET = "\033[0m"
BOLD = "\033[1m"
DIM = "\033[2m"
CYAN = "\033[36m"
GREEN = "\033[32m"
YELLOW = "\033[33m"
RED = "\033[31m"


def c(text, *codes):
    return "".join(codes) + str(text) + RESET


def main() -> None:
    try:
        parser = argparse.ArgumentParser(
            prog="orbits",
            description=(
                "Visualize dependency trees as systems of planets.\n\n"
                "Package sizes are read from the currently active Python environment.\n"
                "Activate your venv before running this script."
            ),
            formatter_class=argparse.RawDescriptionHelpFormatter,
        )
        parser.add_argument(
            "project_dir",
            nargs="?",
            default=None,
            help="Path to project directory (default: current dir)",
        )
        parser.add_argument(
            "--project-type",
            choices=["python", "node"],
            help = "The type of project to use (detected automatically by default)"
        )
        parser.add_argument(
            "--python",
            default=None,
            metavar="PATH",
            help="Explicit Python interpreter to use (overrides $VIRTUAL_ENV)",
        )
        parser.add_argument(
            "--include-dev",
            action="store_true",
            help="Whether to include 'devDependencies'",
        )
        args = parser.parse_args()

        if args.project_dir is None:
            project_dir, project_type = find_root(Path(".").resolve(), args.project_type)
        else:
            project_dir = Path(args.project_dir).resolve()

            if not project_dir.is_dir():
                print(f"Error: '{project_dir}' is not a directory.", file=sys.stderr)
                sys.exit(1)

            project_type = identify_path(project_dir, args.project_type)

        if project_type is None:
            print("Error: couldn't find valid project", file=sys.stderr)
            sys.exit(1)

        try:
            if project_type == "python":
                tree = calculate_tree(project_dir, Path(args.python) if args.python else None)
            elif project_type == "node":
                tree = node.build_tree(project_dir, args.include_dev)
        except NoDependenciesException:
            print(
                c(
                    "No dependencies found. Ensure the project has a pyproject.toml, "
                    "setup.cfg, or requirements.txt.",
                    YELLOW,
                ),
                file=sys.stderr,
            )
            sys.exit(0)

        thread = start_server(tree)

        thread.join()
    except KeyboardInterrupt:
        return
