import argparse
import datetime
from typing import Literal

from rich.console import Console

from asof.canonical_names import CanonicalNames
from asof.conda import get_conda as get_conda
from asof.pypi import get_pypi as get_pypi


def main():
    console = Console()
    options = get_options()

    canonical_names = CanonicalNames.from_options(options, console)
    console.print(
        f"Query: [bold]{options.query}[/bold] [gray]({options.query_type} name)[/gray]",
        highlight=False,
    )
    console.print(canonical_names.pretty, highlight=False)

    get_pypi(options.when, canonical_names.pypi_name).log(console)
    get_conda(options.when, canonical_names.conda_name).log(console)


def datetime_fromisoformat_here(s: str) -> datetime.datetime:
    """Parse datetime from ISO format; add current timezone if not present."""
    dt = datetime.datetime.fromisoformat(s)
    if dt.tzinfo is None:
        tzinfo = datetime.datetime.now().astimezone().tzinfo
        dt = dt.replace(tzinfo=tzinfo)
    return dt


def get_parser() -> argparse.ArgumentParser:
    parser = argparse.ArgumentParser(prog="asof.py")
    parser.add_argument(
        "when",
        help="Date or time of cutoff (ISO format). Only versions released before this time are considered.",
        type=datetime_fromisoformat_here,
    )
    parser.add_argument(
        "query",
        help='Package name (or import name, if query type is "import") to search for latest version.',
    )
    parser.add_argument(
        "--query-type",
        help='Type of query (default: "pypi"). For example, "pypi" matches packages based on the name registered in PyPI. Many, but not all, packages have identical names for the imported module, PyPI package, and conda package.',
        nargs="?",
        choices=["conda", "import", "pypi"],
        default="pypi",
        type=as_query_type,
    )
    return parser


def get_options() -> argparse.Namespace:
    return get_parser().parse_args()


QueryType = Literal["conda", "PyPI", "import"]


def as_query_type(maybe_query_type: str) -> QueryType:
    match maybe_query_type.lower():
        case "conda":
            return "conda"
        case "pypi":
            return "PyPI"
        case "import":
            return "import"
        case _:
            raise ValueError


if __name__ == "__main__":
    main()
