"""Tests for axm_bib.config — email resolution chain."""

from __future__ import annotations

import os
from pathlib import Path
from unittest.mock import patch

import pytest

from axm_bib.config import get_email, resolve_email


class TestGetEmail:
    """get_email() — non-interactive resolution."""

    def test_env_var_takes_priority(self) -> None:
        """UNPAYWALL_EMAIL env var wins over config file."""
        with patch.dict(os.environ, {"UNPAYWALL_EMAIL": "env@test.com"}):
            assert get_email() == "env@test.com"

    def test_config_file_fallback(self, tmp_path: Path) -> None:
        """Reads from config file when no env var."""
        config_file = tmp_path / "config.toml"
        config_file.write_text('email = "file@test.com"\n')

        with (
            patch.dict(os.environ, {}, clear=True),
            patch("axm_bib.config._CONFIG_FILE", config_file),
        ):
            os.environ.pop("UNPAYWALL_EMAIL", None)
            assert get_email() == "file@test.com"

    def test_none_when_not_configured(self, tmp_path: Path) -> None:
        """Returns None when nothing is configured."""
        config_file = tmp_path / "nonexistent.toml"

        with (
            patch.dict(os.environ, {}, clear=True),
            patch("axm_bib.config._CONFIG_FILE", config_file),
        ):
            os.environ.pop("UNPAYWALL_EMAIL", None)
            assert get_email() is None


class TestResolveEmail:
    """resolve_email() — with interactive prompt."""

    def test_returns_env_var_without_prompt(self) -> None:
        """If env var is set, no prompt needed."""
        with patch.dict(os.environ, {"UNPAYWALL_EMAIL": "env@test.com"}):
            assert resolve_email() == "env@test.com"

    def test_interactive_prompt_saves(self, tmp_path: Path) -> None:
        """Prompts user and saves to config file."""
        config_dir = tmp_path / "config"
        config_file = config_dir / "config.toml"

        with (
            patch.dict(os.environ, {}, clear=True),
            patch("axm_bib.config._CONFIG_FILE", config_file),
            patch("axm_bib.config._CONFIG_DIR", config_dir),
            patch("builtins.input", return_value="user@test.com"),
            patch("sys.stdin") as mock_stdin,
        ):
            os.environ.pop("UNPAYWALL_EMAIL", None)
            mock_stdin.isatty.return_value = True
            email = resolve_email()

        assert email == "user@test.com"
        assert config_file.exists()
        assert "user@test.com" in config_file.read_text()

    def test_non_interactive_exits(self, tmp_path: Path) -> None:
        """Non-interactive mode exits with error when no email."""
        config_file = tmp_path / "nonexistent.toml"

        with (
            patch.dict(os.environ, {}, clear=True),
            patch("axm_bib.config._CONFIG_FILE", config_file),
            pytest.raises(SystemExit),
        ):
            os.environ.pop("UNPAYWALL_EMAIL", None)
            resolve_email(interactive=False)

    def test_invalid_email_exits(self, tmp_path: Path) -> None:
        """Invalid email input exits."""
        config_file = tmp_path / "nonexistent.toml"

        with (
            patch.dict(os.environ, {}, clear=True),
            patch("axm_bib.config._CONFIG_FILE", config_file),
            patch("builtins.input", return_value="not-an-email"),
            patch("sys.stdin") as mock_stdin,
            pytest.raises(SystemExit),
        ):
            os.environ.pop("UNPAYWALL_EMAIL", None)
            mock_stdin.isatty.return_value = True
            resolve_email()
