"""Tests for loyalty module configuration validators."""
import os

import pytest

from app.modules.loyalty.config import ModuleConfig


@pytest.mark.unit
@pytest.mark.loyalty
class TestGoogleWalletConfigValidator:
    """Validator must fail fast when the SA path is set but unreachable."""

    def test_unset_path_is_allowed(self, monkeypatch):
        """Google Wallet config is optional — None passes."""
        monkeypatch.delenv("LOYALTY_GOOGLE_SERVICE_ACCOUNT_JSON", raising=False)
        monkeypatch.delenv("LOYALTY_GOOGLE_ISSUER_ID", raising=False)
        cfg = ModuleConfig(_env_file=None)
        assert cfg.google_service_account_json is None
        assert cfg.is_google_wallet_enabled is False

    def test_existing_file_passes(self, tmp_path, monkeypatch):
        """A real file path passes and is returned expanded."""
        sa_file = tmp_path / "fake-sa.json"
        sa_file.write_text("{}")
        monkeypatch.setenv("LOYALTY_GOOGLE_SERVICE_ACCOUNT_JSON", str(sa_file))
        monkeypatch.setenv("LOYALTY_GOOGLE_ISSUER_ID", "1234567890")
        cfg = ModuleConfig(_env_file=None)
        assert cfg.google_service_account_json == str(sa_file)
        assert cfg.is_google_wallet_enabled is True

    def test_missing_file_raises(self, tmp_path, monkeypatch):
        """A path that does not exist raises a clear error at import time."""
        bogus = tmp_path / "does-not-exist.json"
        monkeypatch.setenv("LOYALTY_GOOGLE_SERVICE_ACCOUNT_JSON", str(bogus))
        with pytest.raises(ValueError, match="no file exists"):
            ModuleConfig(_env_file=None)

    def test_unreadable_file_raises(self, tmp_path, monkeypatch):
        """A path that exists but is not readable raises a clear error."""
        sa_file = tmp_path / "no-read.json"
        sa_file.write_text("{}")
        os.chmod(sa_file, 0o000)
        try:
            monkeypatch.setenv(
                "LOYALTY_GOOGLE_SERVICE_ACCOUNT_JSON", str(sa_file)
            )
            # Skip if running as root (root bypasses unix file perms)
            if os.geteuid() == 0:
                pytest.skip("Cannot test unreadable file as root")
            with pytest.raises(ValueError, match="not readable"):
                ModuleConfig(_env_file=None)
        finally:
            os.chmod(sa_file, 0o600)

    def test_tilde_path_is_expanded(self, tmp_path, monkeypatch):
        """Leading ~ is expanded so deployments can use ~/apps/orion/..."""
        # Plant the file at $HOME/.../fake-sa.json then reference via ~
        home = tmp_path / "home"
        home.mkdir()
        sa_dir = home / "apps" / "orion"
        sa_dir.mkdir(parents=True)
        sa_file = sa_dir / "fake-sa.json"
        sa_file.write_text("{}")

        monkeypatch.setenv("HOME", str(home))
        monkeypatch.setenv(
            "LOYALTY_GOOGLE_SERVICE_ACCOUNT_JSON",
            "~/apps/orion/fake-sa.json",
        )
        cfg = ModuleConfig(_env_file=None)
        assert cfg.google_service_account_json == str(sa_file)


@pytest.mark.unit
@pytest.mark.loyalty
class TestAppleWalletEnabledFlag:
    """is_apple_wallet_enabled is a derived flag for the storefront UI."""

    def test_disabled_when_unset(self, monkeypatch):
        for var in (
            "LOYALTY_APPLE_PASS_TYPE_ID",
            "LOYALTY_APPLE_TEAM_ID",
            "LOYALTY_APPLE_WWDR_CERT_PATH",
            "LOYALTY_APPLE_SIGNER_CERT_PATH",
            "LOYALTY_APPLE_SIGNER_KEY_PATH",
        ):
            monkeypatch.delenv(var, raising=False)
        cfg = ModuleConfig(_env_file=None)
        assert cfg.is_apple_wallet_enabled is False

    def test_enabled_when_all_set(self, monkeypatch):
        monkeypatch.setenv("LOYALTY_APPLE_PASS_TYPE_ID", "pass.com.x.y")
        monkeypatch.setenv("LOYALTY_APPLE_TEAM_ID", "ABCD1234")
        monkeypatch.setenv("LOYALTY_APPLE_WWDR_CERT_PATH", "/tmp/wwdr.pem")
        monkeypatch.setenv("LOYALTY_APPLE_SIGNER_CERT_PATH", "/tmp/signer.pem")
        monkeypatch.setenv("LOYALTY_APPLE_SIGNER_KEY_PATH", "/tmp/signer.key")
        cfg = ModuleConfig(_env_file=None)
        assert cfg.is_apple_wallet_enabled is True
