"""Tests for complyform.core.auth.license.LicenseManager."""

from __future__ import annotations

import os
import stat
from datetime import UTC, datetime, timedelta

from complyform.core.auth.license import LicenseCache, LicenseManager


def _make_cache(
    *,
    tier: str = "pro",
    last_validated_at: str | None = None,
    expires_at: str | None = None,
) -> LicenseCache:
    if last_validated_at is None:
        last_validated_at = datetime.now(UTC).isoformat()
    return LicenseCache(
        cache_version=1,
        key_hash="sha256:abcdef",
        tier=tier,
        assess_frameworks=["all"],
        remediate_frameworks=["soc2", "hipaa"],
        features=["html_report"],
        project_limit=10,
        expires_at=expires_at,
        last_validated_at=last_validated_at,
        batch_limit=10,
        discover_limit=10,
        scan_sources=["local_state", "gcs"],
    )


class TestLoadCache:
    def test_returns_none_when_no_file(self, tmp_path: object) -> None:
        from pathlib import Path

        assert isinstance(tmp_path, Path)
        mgr = LicenseManager(config_dir=tmp_path)
        assert mgr.load_cache() is None

    def test_returns_none_on_corrupt_file(self, tmp_path: object) -> None:
        from pathlib import Path

        assert isinstance(tmp_path, Path)
        (tmp_path / "license_cache.json").write_text("not json")
        mgr = LicenseManager(config_dir=tmp_path)
        assert mgr.load_cache() is None


class TestSaveCache:
    def test_creates_file_with_0600(self, tmp_path: object) -> None:
        from pathlib import Path

        assert isinstance(tmp_path, Path)
        mgr = LicenseManager(config_dir=tmp_path)
        cache = _make_cache()
        mgr.save_cache(cache)
        path = tmp_path / "license_cache.json"
        assert path.exists()
        mode = stat.S_IMODE(os.stat(path).st_mode)
        assert mode == 0o600

    def test_roundtrip(self, tmp_path: object) -> None:
        from pathlib import Path

        assert isinstance(tmp_path, Path)
        mgr = LicenseManager(config_dir=tmp_path)
        original = _make_cache(tier="team")
        mgr.save_cache(original)
        loaded = mgr.load_cache()
        assert loaded is not None
        assert loaded.tier == "team"
        assert loaded.key_hash == "sha256:abcdef"


class TestGracePeriod:
    def test_recent_timestamp_within_grace(self) -> None:
        mgr = LicenseManager()
        cache = _make_cache(
            last_validated_at=datetime.now(UTC).isoformat(),
        )
        assert mgr.is_within_grace_period(cache) is True

    def test_old_timestamp_outside_grace(self) -> None:
        mgr = LicenseManager()
        old = (datetime.now(UTC) - timedelta(days=8)).isoformat()
        cache = _make_cache(last_validated_at=old)
        assert mgr.is_within_grace_period(cache) is False


class TestCacheFreshness:
    def test_recent_is_fresh(self) -> None:
        mgr = LicenseManager()
        cache = _make_cache(
            last_validated_at=(datetime.now(UTC) - timedelta(minutes=30)).isoformat(),
        )
        assert mgr.is_cache_fresh(cache) is True

    def test_old_is_stale(self) -> None:
        mgr = LicenseManager()
        cache = _make_cache(
            last_validated_at=(datetime.now(UTC) - timedelta(hours=2)).isoformat(),
        )
        assert mgr.is_cache_fresh(cache) is False


class TestResolveTierInfo:
    def test_no_cache_returns_community(self, tmp_path: object) -> None:
        from pathlib import Path

        assert isinstance(tmp_path, Path)
        mgr = LicenseManager(config_dir=tmp_path)
        ti = mgr.resolve_tier_info()
        assert ti.tier == "community"

    def test_valid_cache_returns_cached_tier(self, tmp_path: object) -> None:
        from pathlib import Path

        assert isinstance(tmp_path, Path)
        mgr = LicenseManager(config_dir=tmp_path)
        cache = _make_cache(tier="pro")
        mgr.save_cache(cache)
        ti = mgr.resolve_tier_info()
        assert ti.tier == "pro"

    def test_expired_cache_beyond_grace_returns_community(
        self, tmp_path: object
    ) -> None:
        from pathlib import Path

        assert isinstance(tmp_path, Path)
        mgr = LicenseManager(config_dir=tmp_path)
        old = (datetime.now(UTC) - timedelta(days=8)).isoformat()
        cache = _make_cache(tier="pro", last_validated_at=old)
        mgr.save_cache(cache)
        ti = mgr.resolve_tier_info()
        assert ti.tier == "community"


class TestClearCache:
    def test_clears_existing(self, tmp_path: object) -> None:
        from pathlib import Path

        assert isinstance(tmp_path, Path)
        mgr = LicenseManager(config_dir=tmp_path)
        cache = _make_cache()
        mgr.save_cache(cache)
        assert mgr.load_cache() is not None
        mgr.clear_cache()
        assert mgr.load_cache() is None

    def test_clear_nonexistent_is_noop(self, tmp_path: object) -> None:
        from pathlib import Path

        assert isinstance(tmp_path, Path)
        mgr = LicenseManager(config_dir=tmp_path)
        mgr.clear_cache()  # Should not raise


class TestAutoRefresh:
    def test_returns_none_on_fresh_cache(self, tmp_path: object) -> None:
        from pathlib import Path

        from complyform.core.errors import RemediationTierError

        assert isinstance(tmp_path, Path)
        mgr = LicenseManager(config_dir=tmp_path)
        cache = _make_cache()
        mgr.save_cache(cache)
        err = RemediationTierError("hipaa", "community")
        result = mgr.attempt_auto_refresh(err)
        assert result is None

    def test_returns_none_when_no_cache(self, tmp_path: object) -> None:
        from pathlib import Path

        from complyform.core.errors import RemediationTierError

        assert isinstance(tmp_path, Path)
        mgr = LicenseManager(config_dir=tmp_path)
        err = RemediationTierError("hipaa", "community")
        result = mgr.attempt_auto_refresh(err)
        assert result is None
