#!/usr/bin/env python3
"""
Tests for Operator Report generator (Layer 5).
"""

import unittest
import tempfile
import shutil
import json
from pathlib import Path
import sys

# Add project root to path
sys.path.insert(0, str(Path(__file__).parent.parent))

from tools.factory import create_artifact, persist_artifact
from tools.operator_report import generate_report


class TestOperatorReport(unittest.TestCase):
    def setUp(self):
        self.test_dir = Path(tempfile.mkdtemp())
        self.artifact_dir = self.test_dir / "memory"
        self.artifact_dir.mkdir()
        self.reports_dir = self.test_dir / "reports"
        
        # Create a couple of test artifacts
        self.artifact_a_data = create_artifact(
            "decision",
            {
                "title": "Report Test Artifact A",
                "context": "Context for report test A",
                "options_considered": ["Opt1"],
                "chosen_option": "Opt1",
                "reasoning": "Reason A",
                "constraints": [],
                "assumptions": [],
                "confidence": 0.9,
                "expected_outcome": "Outcome A",
                "category": "test"
            }
        )
        persist_artifact(self.artifact_a_data, self.artifact_dir / "decisions")
        
        self.artifact_b_data = create_artifact(
            "decision",
            {
                "title": "Report Test Artifact B",
                "context": "Context for report test B",
                "options_considered": ["Opt2"],
                "chosen_option": "Opt2",
                "reasoning": "Reason B",
                "constraints": [],
                "assumptions": [],
                "confidence": 0.8,
                "expected_outcome": "Outcome B",
                "category": "test"
            }
        )
        persist_artifact(self.artifact_b_data, self.artifact_dir / "decisions")
    
    def tearDown(self):
        shutil.rmtree(self.test_dir)
    
    def test_generate_report_creates_file(self):
        """Generate report creates a markdown file."""
        exit_code = generate_report(self.artifact_dir, self.reports_dir)
        
        self.assertEqual(exit_code, 0)
        self.assertTrue(self.reports_dir.exists())
        
        # Check report file exists
        report_files = list(self.reports_dir.glob("operator_report_*.md"))
        self.assertEqual(len(report_files), 1)
    
    def test_report_contains_expected_headings(self):
        """Report file contains expected sections."""
        exit_code = generate_report(self.artifact_dir, self.reports_dir)
        self.assertEqual(exit_code, 0)
        
        report_file = list(self.reports_dir.glob("operator_report_*.md"))[0]
        
        with open(report_file, 'r') as f:
            content = f.read()
        
        # Check for expected headings
        self.assertIn("# Novyx Core Operator Report", content)
        self.assertIn("## 🛡️ Sentinel Integrity Summary", content)
        self.assertIn("## 📊 Graph Statistics", content)
        self.assertIn("## 📅 New Artifacts Since Last Report", content)
        self.assertIn("## ⚠️ Risk Notes", content)
    
    def test_report_shows_artifact_counts(self):
        """Report shows correct artifact counts."""
        exit_code = generate_report(self.artifact_dir, self.reports_dir)
        self.assertEqual(exit_code, 0)
        
        report_file = list(self.reports_dir.glob("operator_report_*.md"))[0]
        
        with open(report_file, 'r') as f:
            content = f.read()
        
        # Should show 2 artifacts (we created 2 decisions) - check for the number
        self.assertIn("Total artifacts:** 2", content)
    
    def test_report_with_no_artifacts(self):
        """Report handles empty directory gracefully."""
        empty_dir = self.test_dir / "empty"
        empty_dir.mkdir()
        
        exit_code = generate_report(empty_dir, self.reports_dir)
        self.assertEqual(exit_code, 0)
        
        report_file = list(self.reports_dir.glob("operator_report_*.md"))[0]
        
        with open(report_file, 'r') as f:
            content = f.read()
        
        self.assertIn("Total artifacts:** 0", content)
    
    def test_multiple_reports_track_new_artifacts(self):
        """Second report shows only new artifacts since first report."""
        # Generate first report
        exit_code1 = generate_report(self.artifact_dir, self.reports_dir)
        self.assertEqual(exit_code1, 0)
        
        # Create a new artifact
        self.artifact_c_data = create_artifact(
            "decision",
            {
                "title": "Report Test Artifact C (New)",
                "context": "Context for report test C",
                "options_considered": ["Opt3"],
                "chosen_option": "Opt3",
                "reasoning": "Reason C",
                "constraints": [],
                "assumptions": [],
                "confidence": 0.7,
                "expected_outcome": "Outcome C",
                "category": "test"
            }
        )
        persist_artifact(self.artifact_c_data, self.artifact_dir / "decisions")
        
        # Generate second report (use a different date to avoid collision)
        import time
        time.sleep(0.1)
        
        exit_code2 = generate_report(self.artifact_dir, self.reports_dir)
        self.assertEqual(exit_code2, 0)
        
        # Check second report
        report_files = sorted(self.reports_dir.glob("operator_report_*.md"))
        second_report = report_files[-1]
        
        with open(second_report, 'r') as f:
            content = f.read()
        
        # Second report should mention the last report date
        self.assertIn("Last report date:", content)


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