"""Input detection for huntpdf queries."""

import re
from dataclasses import dataclass
from enum import Enum

from huntpdf.errors import InputNotRecognized


class InputType(Enum):
    URL = "url"
    DOI = "doi"
    PMC_ID = "pmc_id"
    ARXIV_ID = "arxiv_id"
    PMID = "pmid"


@dataclass
class DetectedInput:
    input_type: InputType
    value: str


_DOI_RE = re.compile(r"^10\.\d{4,9}/[^\s]+$")
_PMC_RE = re.compile(r"^PMC\d+$", re.IGNORECASE)
_ARXIV_NEW_RE = re.compile(r"^\d{4}\.\d{4,5}(v\d+)?$")
_ARXIV_OLD_RE = re.compile(r"^[a-z-]+/\d{7}(v\d+)?$")
_PMID_RE = re.compile(r"^\d{1,8}$")


def detect(query: str) -> DetectedInput:
    """Classify a query string and return a DetectedInput."""
    query = query.strip()

    if query.startswith("http://") or query.startswith("https://"):
        return DetectedInput(InputType.URL, query)

    if query.startswith("doi:"):
        value = query[len("doi:") :].strip()
        if _DOI_RE.match(value):
            return DetectedInput(InputType.DOI, value)

    if _DOI_RE.match(query):
        return DetectedInput(InputType.DOI, query)

    if _PMC_RE.match(query):
        return DetectedInput(InputType.PMC_ID, query)

    if query.startswith("arXiv:"):
        value = query[len("arXiv:") :]
        if _ARXIV_NEW_RE.match(value) or _ARXIV_OLD_RE.match(value):
            return DetectedInput(InputType.ARXIV_ID, value)

    if _ARXIV_NEW_RE.match(query) or _ARXIV_OLD_RE.match(query):
        return DetectedInput(InputType.ARXIV_ID, query)

    if query.startswith("PMID:"):
        value = query[len("PMID:") :].strip()
        if _PMID_RE.match(value):
            return DetectedInput(InputType.PMID, value)

    if _PMID_RE.match(query):
        return DetectedInput(InputType.PMID, query)

    raise InputNotRecognized(f"Cannot classify input: {query}")
