"""Tests for huntpdf.detect."""

import pytest

from huntpdf.detect import DetectedInput, InputType, detect
from huntpdf.errors import InputNotRecognized


class TestURLDetection:
    def test_https_url(self):
        result = detect("https://arxiv.org/abs/2301.00001")
        assert result == DetectedInput(InputType.URL, "https://arxiv.org/abs/2301.00001")

    def test_http_url(self):
        result = detect("http://example.com/paper.pdf")
        assert result == DetectedInput(InputType.URL, "http://example.com/paper.pdf")

    def test_doi_url_detected_as_url(self):
        result = detect("https://doi.org/10.1000/xyz123")
        assert result.input_type == InputType.URL


class TestDOIDetection:
    def test_bare_doi(self):
        result = detect("10.1038/nature12373")
        assert result == DetectedInput(InputType.DOI, "10.1038/nature12373")

    def test_doi_with_prefix(self):
        result = detect("doi:10.1038/nature12373")
        assert result == DetectedInput(InputType.DOI, "10.1038/nature12373")

    def test_doi_with_prefix_and_space(self):
        result = detect("doi: 10.1038/nature12373")
        assert result == DetectedInput(InputType.DOI, "10.1038/nature12373")

    def test_doi_long_registrant(self):
        result = detect("10.123456789/abc")
        assert result == DetectedInput(InputType.DOI, "10.123456789/abc")


class TestPMCDetection:
    def test_pmc_id(self):
        result = detect("PMC1234567")
        assert result == DetectedInput(InputType.PMC_ID, "PMC1234567")

    def test_pmc_lowercase(self):
        result = detect("pmc1234567")
        assert result == DetectedInput(InputType.PMC_ID, "pmc1234567")

    def test_pmc_mixed_case(self):
        result = detect("Pmc123")
        assert result == DetectedInput(InputType.PMC_ID, "Pmc123")


class TestArxivDetection:
    def test_new_format(self):
        result = detect("2301.00001")
        assert result == DetectedInput(InputType.ARXIV_ID, "2301.00001")

    def test_new_format_five_digits(self):
        result = detect("2301.12345")
        assert result == DetectedInput(InputType.ARXIV_ID, "2301.12345")

    def test_new_format_versioned(self):
        result = detect("2301.00001v2")
        assert result == DetectedInput(InputType.ARXIV_ID, "2301.00001v2")

    def test_old_format(self):
        result = detect("hep-th/0601001")
        assert result == DetectedInput(InputType.ARXIV_ID, "hep-th/0601001")

    def test_old_format_versioned(self):
        result = detect("cond-mat/0601001v3")
        assert result == DetectedInput(InputType.ARXIV_ID, "cond-mat/0601001v3")

    def test_arxiv_prefix_new(self):
        result = detect("arXiv:2301.00001")
        assert result == DetectedInput(InputType.ARXIV_ID, "2301.00001")

    def test_arxiv_prefix_old(self):
        result = detect("arXiv:hep-th/0601001")
        assert result == DetectedInput(InputType.ARXIV_ID, "hep-th/0601001")


class TestPMIDDetection:
    def test_bare_pmid(self):
        result = detect("12345678")
        assert result == DetectedInput(InputType.PMID, "12345678")

    def test_short_pmid(self):
        result = detect("1")
        assert result == DetectedInput(InputType.PMID, "1")

    def test_pmid_with_prefix(self):
        result = detect("PMID:12345678")
        assert result == DetectedInput(InputType.PMID, "12345678")

    def test_pmid_with_prefix_and_space(self):
        result = detect("PMID: 12345678")
        assert result == DetectedInput(InputType.PMID, "12345678")


class TestUnrecognizedInput:
    def test_random_string(self):
        with pytest.raises(InputNotRecognized):
            detect("not a valid identifier")

    def test_empty_string(self):
        with pytest.raises(InputNotRecognized):
            detect("")

    def test_too_long_bare_digits(self):
        with pytest.raises(InputNotRecognized):
            detect("123456789")


class TestWhitespaceStripping:
    def test_leading_trailing_spaces(self):
        result = detect("  10.1038/nature12373  ")
        assert result == DetectedInput(InputType.DOI, "10.1038/nature12373")
