import logging
from functools import lru_cache

import pytest
from debian.debian_support import DpkgArchTable

from debputy._deb_options_profiles import DebBuildOptionsAndProfiles
from debputy.architecture_support import DpkgArchitectureBuildProcessValuesTable
from debputy.lsp.maint_prefs import (
    EffectiveFormattingPreference,
    MaintainerPreferenceTable,
)
from debputy.packages import DctrlParser
from debputy.util import setup_logging, change_log_level

try:
    from debputy.lsp.spellchecking import (
        disable_spellchecking,
        Spellchecker,
        HunspellSpellchecker,
    )
except ImportError:

    def disable_spellchecking() -> None:
        pass


from debputy.lsp.spellchecking import _HAS_HUNSPELL, _testing_set_default_spellchecker

try:
    from lsprotocol import types
except ImportError:
    HAS_LSPROTOCOL = False
else:
    HAS_LSPROTOCOL = True


@pytest.fixture(scope="session", autouse=True)
def enable_logging() -> None:
    if not HAS_LSPROTOCOL:
        pytest.skip("Missing python3-lsprotocol")
    setup_logging(reconfigure_logging=True)
    change_log_level(logging.INFO)


@pytest.fixture(scope="session", autouse=True)
def disable_spellchecking_fixture() -> None:
    # CI/The buildd does not install relevant, so this is mostly about ensuring
    # consistent behavior between clean and "unclean" build/test environments
    disable_spellchecking()


@lru_cache
def _spellchecker() -> Spellchecker:
    return HunspellSpellchecker()


@pytest.fixture(scope="function")
def spellchecking_enabled() -> None:
    if not _HAS_HUNSPELL:
        pytest.skip("Missing python3-hunspell hunspell-en-us")

    saved_spellchecker = _testing_set_default_spellchecker(_spellchecker())
    try:
        yield
    finally:
        _testing_set_default_spellchecker(saved_spellchecker)


@pytest.fixture
def lint_dctrl_parser(
    dpkg_arch_query: DpkgArchTable,
    amd64_dpkg_architecture_variables: DpkgArchitectureBuildProcessValuesTable,
    no_profiles_or_build_options: DebBuildOptionsAndProfiles,
) -> DctrlParser:
    return DctrlParser(
        frozenset(),
        frozenset(),
        True,
        True,
        amd64_dpkg_architecture_variables,
        dpkg_arch_query,
        no_profiles_or_build_options,
    )


@pytest.fixture(scope="session")
def maintainer_preference_table() -> MaintainerPreferenceTable:
    return MaintainerPreferenceTable.load_preferences()
