#!/usr/bin/env python3
"""Tests for health check module."""

import json
import os
import sys
import tempfile
import unittest
from pathlib import Path
from unittest.mock import patch

sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
from tools.health_check import HealthCheck


class TestHealthCheckIndividual(unittest.TestCase):
    """Test individual health checks."""

    def test_check_disk_space(self):
        ok, detail = HealthCheck.check_disk_space()
        self.assertIsInstance(ok, bool)
        self.assertIn("GB", detail)
        self.assertIn("free", detail)

    def test_check_memory_file_exists(self):
        with tempfile.NamedTemporaryFile(mode="w", suffix=".md", delete=False) as f:
            f.write("# Memory\nTest content\n")
            f.flush()
            with patch.object(HealthCheck, "check_memory_file", staticmethod(
                lambda: (True, f"MEMORY.md: 2 lines, {os.path.getsize(f.name)} bytes")
            )):
                ok, detail = HealthCheck.check_memory_file()
                self.assertTrue(ok)
            os.unlink(f.name)

    def test_check_skills_count(self):
        with tempfile.TemporaryDirectory() as tmp:
            # Create a fake skill
            skill_dir = Path(tmp) / "test-skill"
            skill_dir.mkdir()
            (skill_dir / "SKILL.md").write_text("---\nname: test\n---\n# Test")

            with patch.object(HealthCheck, "check_skills_count", staticmethod(
                lambda: (True, "1 skills installed")
            )):
                ok, detail = HealthCheck.check_skills_count()
                self.assertTrue(ok)
                self.assertIn("1", detail)

    def test_check_cron_jobs_valid(self):
        with tempfile.NamedTemporaryFile(mode="w", suffix=".json", delete=False) as f:
            json.dump([
                {"id": "1", "status": "active"},
                {"id": "2", "status": "paused"},
            ], f)
            f.flush()

            # Test the logic directly
            jobs = json.loads(Path(f.name).read_text())
            active = sum(1 for j in jobs if j.get("status") == "active")
            self.assertEqual(active, 1)
            os.unlink(f.name)


class TestHealthCheckRunner(unittest.TestCase):
    """Test the health check runner."""

    def test_check_method(self):
        hc = HealthCheck()
        result = hc.check("test_pass", lambda: (True, "all good"))
        self.assertEqual(result["status"], "PASS")
        self.assertEqual(result["detail"], "all good")

    def test_check_failure(self):
        hc = HealthCheck()
        result = hc.check("test_fail", lambda: (False, "broken"))
        self.assertEqual(result["status"], "FAIL")

    def test_check_exception(self):
        hc = HealthCheck()
        def boom():
            raise RuntimeError("kaboom")
        result = hc.check("test_error", boom)
        self.assertEqual(result["status"], "ERROR")
        self.assertIn("kaboom", result["detail"])

    def test_check_critical_flag(self):
        hc = HealthCheck()
        result = hc.check("test_crit", lambda: (False, "bad"), critical=True)
        self.assertTrue(result["critical"])

    def test_run_all_returns_structure(self):
        hc = HealthCheck()
        result = hc.run_all()
        self.assertIn("timestamp", result)
        self.assertIn("total", result)
        self.assertIn("passed", result)
        self.assertIn("failed", result)
        self.assertIn("healthy", result)
        self.assertIn("checks", result)
        self.assertIsInstance(result["checks"], list)
        self.assertGreater(result["total"], 0)

    def test_format_report(self):
        hc = HealthCheck()
        result = hc.run_all()
        report = hc.format_report(result)
        self.assertIn("Ezra Health Check", report)
        self.assertIn("HEALTHY", report.upper())
        self.assertIn("|", report)  # Table format


class TestHealthCheckLive(unittest.TestCase):
    """Live checks against actual infrastructure (may fail in CI)."""

    def test_disk_space_live(self):
        ok, detail = HealthCheck.check_disk_space()
        # Should always work on a real system
        self.assertIsInstance(ok, bool)
        self.assertRegex(detail, r'\d+\.\d+GB free')

    def test_hermes_gateway_live(self):
        ok, detail = HealthCheck.check_hermes_gateway()
        # Just verify it runs without error
        self.assertIsInstance(ok, bool)
        self.assertIsInstance(detail, str)


if __name__ == "__main__":
    unittest.main()
