"""Utilities for TypeID."""

import re

import typer


def is_type_id(s: str, type: str | None = None, domain: str | None = None):
    """Is given string a valid TypeID."""
    type_pattern = type if type else r"[a-z]{1,6}"
    domain_pattern = domain if domain else r"[a-z0-9-.]{2,56}"
    suffix_pattern = r"[01234567][0123456789abcdefghjkmnpqrstvwxyz]{25}"
    pattern = re.compile(f"^{type_pattern}_{domain_pattern}_{suffix_pattern}$")

    return pattern.match(s)


def is_experiment_id(s: str):
    """Is given string a valid experiment TypeID."""
    return is_type_id(s, type="exp")


def is_project_id(s: str):
    """Is given string a valid project TypeID."""
    return is_type_id(s, type="proj")


def validate_type_id(value: str, *, required_type: str | None = None):
    """Validate TypeID."""

    if value is None:
        return None

    if not is_type_id(value):
        raise typer.BadParameter("invalid ID")

    type_, domain, suffix = value.split("_")
    if type_ is not None and type_ != required_type:
        raise typer.BadParameter(f"invalid ID type. Expected {required_type!r}, got {type_!r}")

    return value


def get_type_id_parts(value: str) -> tuple[str, str, str]:
    """Extract the type, domain and suffix of a TypeID."""
    if not is_type_id(value):
        raise typer.BadParameter("invalid ID")

    type_, domain, suffix = value.split("_")
    return type_, domain, suffix


def get_type_id_domain(value: str) -> str:
    """Extract the domain of a TypeID."""
    _, domain, _ = get_type_id_parts(value)
    return domain
