"""Tests for the TransparencyDashboard -- privacy manifest, resource monitor, and transparency manager."""

from __future__ import annotations

import json

import pytest

from llmhosts.security.privacy_manifest import PrivacyManifest
from llmhosts.security.resource_monitor import ResourceMonitor, ResourceSnapshot
from llmhosts.security.transparency import TransparencyConfig, TransparencyManager, TransparencyReport


class TestPrivacyManifest:
    def test_generate_default_manifest(self) -> None:
        manifest = PrivacyManifest.generate()
        assert manifest.version == "1.0"
        assert manifest.data_collection["telemetry"] is False
        assert manifest.data_collection["crash_reports"] is False
        assert manifest.data_collection["usage_analytics"] is False
        assert manifest.gpu_usage["mining"] is False
        assert manifest.gpu_usage["third_party_compute"] is False

    def test_manifest_to_json(self) -> None:
        manifest = PrivacyManifest.generate()
        json_str = manifest.to_json()
        parsed = json.loads(json_str)
        assert parsed["version"] == "1.0"
        assert "network_connections" in parsed
        assert "local_storage" in parsed

    def test_manifest_local_storage_paths(self) -> None:
        manifest = PrivacyManifest.generate()
        assert len(manifest.local_storage) >= 3
        purposes = [s["purpose"] for s in manifest.local_storage]
        assert any("config" in p.lower() for p in purposes)
        assert any("audit" in p.lower() for p in purposes)
        assert any("cache" in p.lower() for p in purposes)

    def test_manifest_network_connections_local(self) -> None:
        manifest = PrivacyManifest.generate()
        assert len(manifest.network_connections) >= 1
        assert any("ollama" in c.get("purpose", "").lower() for c in manifest.network_connections)

    def test_manifest_permissions_never_used(self) -> None:
        manifest = PrivacyManifest.generate()
        assert "camera" in manifest.permissions_never_used
        assert "microphone" in manifest.permissions_never_used
        assert "location" in manifest.permissions_never_used

    def test_manifest_gpu_policy(self) -> None:
        manifest = PrivacyManifest.generate()
        assert manifest.gpu_usage["purpose"] == "LLM inference only"
        assert manifest.gpu_usage["mining"] is False

    def test_manifest_to_dict(self) -> None:
        manifest = PrivacyManifest.generate()
        d = manifest.to_dict()
        assert isinstance(d, dict)
        assert "version" in d


class TestResourceMonitor:
    def test_snapshot_returns_data(self) -> None:
        monitor = ResourceMonitor()
        snap = monitor.snapshot()
        assert isinstance(snap, ResourceSnapshot)
        assert snap.timestamp > 0
        assert snap.memory_mb >= 0

    def test_request_tracking(self) -> None:
        monitor = ResourceMonitor()
        assert monitor._active_requests == 0
        monitor.increment_requests()
        assert monitor._active_requests == 1
        monitor.increment_requests()
        assert monitor._active_requests == 2
        monitor.decrement_requests()
        assert monitor._active_requests == 1
        monitor.decrement_requests()
        assert monitor._active_requests == 0

    def test_decrement_does_not_go_negative(self) -> None:
        monitor = ResourceMonitor()
        monitor.decrement_requests()
        assert monitor._active_requests == 0

    def test_history_accumulates(self) -> None:
        monitor = ResourceMonitor()
        monitor.snapshot()
        monitor.snapshot()
        monitor.snapshot()
        history = monitor.get_history(minutes=60)
        assert len(history) == 3

    def test_history_max_size(self) -> None:
        monitor = ResourceMonitor()
        monitor._max_history = 5
        for _ in range(10):
            monitor.snapshot()
        assert len(monitor._history) == 5

    def test_get_summary(self) -> None:
        monitor = ResourceMonitor()
        monitor.snapshot()
        summary = monitor.get_summary()
        assert "avg_cpu_percent" in summary
        assert "avg_memory_mb" in summary
        assert "active_requests" in summary

    def test_get_summary_empty(self) -> None:
        monitor = ResourceMonitor()
        summary = monitor.get_summary()
        assert "message" in summary

    def test_snapshot_to_dict(self) -> None:
        snap = ResourceSnapshot(cpu_percent=5.5, memory_mb=128.3)
        d = snap.to_dict()
        assert d["cpu_percent"] == 5.5
        assert d["memory_mb"] == 128.3


class TestTransparencyManager:
    def test_create_manager(self) -> None:
        config = TransparencyConfig()
        manager = TransparencyManager(config)
        assert manager.config.privacy_manifest is True

    def test_generate_report(self) -> None:
        config = TransparencyConfig()
        manager = TransparencyManager(config)
        report = manager.generate_report()
        assert isinstance(report, TransparencyReport)
        assert report.telemetry_enabled is False
        assert "pid" in report.process_info

    @pytest.mark.asyncio
    async def test_write_manifest(self, tmp_path, monkeypatch) -> None:
        config = TransparencyConfig()
        manager = TransparencyManager(config)
        # Monkey-patch the manifest path to use tmp_path
        monkeypatch.setattr(manager, "_get_manifest_path", lambda: tmp_path / "privacy-manifest.json")
        path = await manager.write_manifest()
        assert path.exists()
        content = json.loads(path.read_text())
        assert content["version"] == "1.0"
        assert content["data_collection"]["telemetry"] is False

    def test_config_defaults(self) -> None:
        config = TransparencyConfig()
        assert config.privacy_manifest is True
        assert config.resource_monitor is True
        assert config.activity_log_retention_hours == 24
