#!/usr/bin/env python3
"""커버리지 보완을 위한 엣지 케이스 테스트"""

import os
import sys
import tempfile
import unittest
from pathlib import Path

sys.path.insert(0, str(Path(__file__).parent.parent))

from base_reviewer import ReviewerInterface
from code_reviewer import CodeReviewer
from red_team_orchestrator import RedTeamOrchestrator


class MockReviewer(ReviewerInterface):
    """테스트용 목 리뷰어"""

    def review(self, doc):
        issues = [{"severity": "low", "description": "test issue"}]
        return {
            "risk_level": self._assess_risk(issues),
            "issues": issues,
            "recommendation": self._get_recommendation(self._assess_risk(issues)),
        }


class TestCodeReviewerEdgeCases(unittest.TestCase):
    """Code Reviewer 엣지 케이스 테스트"""

    def setUp(self):
        self.reviewer = CodeReviewer()

    def test_assess_risk_many_medium_issues(self):
        """6개 이상의 medium 이슈 → high 리스크"""
        issues = [{"severity": "medium"} for _ in range(6)]
        result = self.reviewer._assess_risk(issues)
        self.assertEqual(result, "high")

    def test_assess_risk_many_high_issues(self):
        """11개 이상의 high 이슈 → critical 리스크"""
        issues = [{"severity": "high"} for _ in range(11)]
        result = self.reviewer._assess_risk(issues)
        self.assertEqual(result, "critical")

    def test_check_dependencies_with_requirements(self):
        """의존성 검사 - requirements.txt 존재"""
        with tempfile.TemporaryDirectory() as tmpdir:
            # Python 파일 생성
            py_file = Path(tmpdir) / "test.py"
            py_file.write_text("# test")

            # requirements.txt 생성
            req_file = Path(tmpdir) / "requirements.txt"
            req_file.write_text("requests==2.28.0\n")

            result = self.reviewer._check_dependencies(str(py_file))
            self.assertIn("vulnerable_deps", result)

    def test_check_dependencies_without_requirements(self):
        """의존성 검사 - requirements.txt 없음"""
        with tempfile.NamedTemporaryFile(mode="w", suffix=".py", delete=False) as f:
            f.write("# test")
            temp_path = f.name

        try:
            result = self.reviewer._check_dependencies(temp_path)
            self.assertEqual(result["vulnerable_deps"], 0)
        finally:
            os.unlink(temp_path)

    def test_check_dependencies_non_python_file(self):
        """의존성 검사 - Python 파일 아님"""
        with tempfile.NamedTemporaryFile(mode="w", suffix=".js", delete=False) as f:
            f.write("// test")
            temp_path = f.name

        try:
            result = self.reviewer._check_dependencies(temp_path)
            self.assertEqual(result["vulnerable_deps"], 0)
        finally:
            os.unlink(temp_path)

    def test_load_file_with_exception(self):
        """파일 로드 - 예외 발생 (권한 없음 등)"""
        # 존재하지 않는 경로
        result = self.reviewer._load_file("/nonexistent/path/file.py")
        self.assertIsNone(result)

    def test_scan_vulnerabilities_all_types(self):
        """취약점 스캔 - 모든 타입"""
        # 여러 취약점이 포함된 코드
        content = """
password = "secret123"
api_key = "abcd1234"
eval(user_input)
os.system(user_input)
../etc/passwd
"""
        vulnerabilities = self.reviewer._scan_vulnerabilities(content)
        # 적어도 일부 취약점이 감지되어야 함
        self.assertGreater(len(vulnerabilities), 0)


class TestRedTeamOrchestratorEdgeCases(unittest.TestCase):
    """Red Team Orchestrator 엣지 케이스 테스트"""

    def setUp(self):
        self.mock_reviewer = MockReviewer()
        self.orchestrator = RedTeamOrchestrator({"mock": self.mock_reviewer})

    def test_review_with_unknown_type(self):
        """알 수 없는 타입으로 리뷰"""
        result = self.orchestrator.review("unknown_type", "test")
        self.assertIn("error", result)
        self.assertEqual(result["risk_level"], "unknown")

    def test_get_available_types(self):
        """사용 가능한 타입 목록"""
        types = self.orchestrator.get_available_types()
        self.assertIn("mock", types)


class TestBaseReviewerEdgeCases(unittest.TestCase):
    """Base Reviewer 엣지 케이스 테스트"""

    def setUp(self):
        self.reviewer = MockReviewer()

    def test_get_recommendation_unknown(self):
        """알 수 없는 리스크 레벨 권장사항"""
        result = self.reviewer._get_recommendation("unknown_level")
        self.assertIn("알 수 없음", result)

    def test_assess_risk_with_unknown_severity(self):
        """알 수 없는 심각도의 이슈"""
        issues = [{"severity": "unknown_severity"}]
        result = self.reviewer._assess_risk(issues)
        # 알 수 없는 심각도는 low로 처리됨
        self.assertEqual(result, "low")

    def test_assess_risk_mixed_severities(self):
        """혼합 심각도 이슈 - 최고 심각도 선택"""
        issues = [{"severity": "low"}, {"severity": "medium"}, {"severity": "high"}, {"severity": "critical"}]
        result = self.reviewer._assess_risk(issues)
        self.assertEqual(result, "critical")


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