"""
PM-Agent v1.2.0 Final Coverage Sprint

冲刺80%覆盖率 - 最后阶段
"""
import os
import sys
import pytest
import tempfile
import shutil
from pathlib import Path
from unittest.mock import Mock, patch, MagicMock
from datetime import datetime

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


class TestSyncPermissionSprint:
    """SyncPermissionService 冲刺"""

    def test_get_project_warnings(self):
        """测试获取项目警告"""
        from backend.services.sync_permission_service import SyncPermissionService
        
        service = SyncPermissionService()
        
        warnings = service._get_project_warnings("test-project")
        
        assert isinstance(warnings, list)

    def test_get_project_warnings_with_git(self):
        """测试带Git的警告"""
        from backend.services.sync_permission_service import SyncPermissionService
        
        service = SyncPermissionService()
        
        warnings = service._get_project_warnings("nonexistent")
        
        assert isinstance(warnings, list)

    def test_check_sync_safety_confidential(self):
        """测试保密项目安全检查"""
        from backend.services.sync_permission_service import SyncPermissionService
        
        service = SyncPermissionService()
        
        result = service.check_sync_safety("confidential-project")
        
        assert 'is_safe' in result
        assert 'checks' in result

    def test_check_sync_safety_inactive(self):
        """测试非活跃项目安全检查"""
        from backend.services.sync_permission_service import SyncPermissionService
        
        service = SyncPermissionService()
        
        result = service.check_sync_safety("inactive-project")
        
        assert 'is_safe' in result


class TestProgressSprint:
    """ProgressService 冲刺"""

    def test_get_project_progress_db_error(self):
        """测试数据库错误"""
        from backend.services.progress_service import ProgressService
        
        service = ProgressService()
        
        progress = service.get_project_progress("test")
        
        assert progress is not None

    def test_calculate_progress_mixed(self):
        """测试混合进度"""
        from backend.services.progress_service import ProgressService, ProjectProgress, RequirementsProgress, BugsProgress, TodosProgress
        
        service = ProgressService()
        
        progress = ProjectProgress(
            project_name="test",
            requirements=RequirementsProgress(total=10, completed=5),
            bugs=BugsProgress(total=10, resolved=0),
            todos=TodosProgress(total=10, completed=10)
        )
        
        result = service.calculate_overall_progress(progress)
        
        assert result >= 0


class TestStatusFeedbackSprint:
    """StatusFeedbackService 冲刺"""

    def test_parse_change_with_full_data(self):
        """测试完整数据解析"""
        from backend.services.status_feedback_service import StatusFeedbackService
        
        service = StatusFeedbackService()
        
        change = {
            'id': '1',
            'title': 'Test',
            'change_type': 'bug',
            'old_status': 'open',
            'new_status': 'closed',
            'old_value': '5',
            'new_value': '0'
        }
        
        event = service._parse_change("test-project", change)
        
        assert event.change_id == '1'

    def test_check_status_with_progress(self):
        """测试带进度的状态检查"""
        from backend.services.status_feedback_service import StatusFeedbackService
        
        mock_client = Mock()
        mock_client.get_project_status.return_value = Mock(status="active", progress=75)
        mock_client.get_project_progress.return_value = Mock(
            requirements_total=10,
            requirements_completed=5,
            requirements_in_progress=3,
            bugs_total=5,
            bugs_resolved=3,
            todos_total=20,
            todos_completed=10
        )
        
        service = StatusFeedbackService(client=mock_client)
        
        result = service.check_status_changes("test-project")
        
        assert 'progress' in result


class TestConfidentialCheckerSprint:
    """ConfidentialChecker 冲刺"""

    def test_check_files_empty(self):
        """测试空目录检查"""
        from backend.services.confidential_checker import SensitiveContentChecker
        
        temp = tempfile.mkdtemp()
        try:
            checker = SensitiveContentChecker()
            result = checker.check_files(temp)
            
            assert result.files_count == 0
        finally:
            shutil.rmtree(temp, ignore_errors=True)

    def test_check_content_edge_case(self):
        """测试边界情况"""
        from backend.services.confidential_checker import SensitiveContentChecker
        
        checker = SensitiveContentChecker()
        
        result = checker.check_content("Hello world")
        
        assert isinstance(result, bool)


class TestDocumentFetcherSprint:
    """DocumentFetcher 冲刺"""

    def test_list_requirement_docs(self):
        """测试列出需求文档"""
        from backend.services.document_fetcher import DocumentFetcher
        
        temp = tempfile.mkdtemp()
        try:
            fetcher = DocumentFetcher()
            docs = fetcher.list_requirement_docs(temp)
            
            assert docs == []
        finally:
            shutil.rmtree(temp, ignore_errors=True)

    def test_list_design_docs(self):
        """测试列出设计文档"""
        from backend.services.document_fetcher import DocumentFetcher
        
        temp = tempfile.mkdtemp()
        try:
            fetcher = DocumentFetcher()
            docs = fetcher.list_design_docs(temp)
            
            assert docs == []
        finally:
            shutil.rmtree(temp, ignore_errors=True)


class TestGitSyncSprint:
    """GitSyncService 冲刺"""

    def test_count_files_nested(self):
        """测试嵌套文件计数"""
        from backend.services.git_sync_service import GitSyncService
        
        temp = tempfile.mkdtemp()
        try:
            sub = os.path.join(temp, "a", "b", "c")
            os.makedirs(sub)
            for i in range(5):
                with open(os.path.join(sub, f"f{i}.txt"), "w") as f:
                    f.write("x")
            
            service = GitSyncService()
            count = service._count_files(temp)
            
            assert count >= 5
        finally:
            shutil.rmtree(temp, ignore_errors=True)


class TestIssueSyncSprint:
    """IssueSyncService 冲刺"""

    def test_get_bugs_summary_with_client(self):
        """测试有客户端BUG统计"""
        from backend.services.issue_sync_service import IssueSyncService
        
        mock_client = Mock()
        mock_client.get_project_bugs.return_value = []
        
        service = IssueSyncService(client=mock_client)
        
        summary = service.get_bugs_summary("test-project")
        
        assert 'total' in summary

    def test_get_requirements_summary_with_client(self):
        """测试有客户端需求统计"""
        from backend.services.issue_sync_service import IssueSyncService
        
        mock_client = Mock()
        mock_client.get_project_requirements.return_value = []
        
        service = IssueSyncService(client=mock_client)
        
        summary = service.get_requirements_summary("test-project")
        
        assert 'total' in summary


class TestOcCollabClientSprint:
    """OcCollabClient 冲刺"""

    @patch('backend.services.oc_collab_client.shutil.which')
    @patch('backend.services.oc_collab_client.subprocess.run')
    def test_get_project_progress_zero(self, mock_run, mock_which):
        """测试零进度"""
        from backend.services.oc_collab_client import OcCollabClient
        
        mock_which.return_value = "/usr/bin/oc-collab"
        
        mock_result = Mock()
        mock_result.returncode = 0
        mock_result.stdout = '{"requirements_total": 0}'
        mock_result.stderr = ''
        mock_run.return_value = mock_result
        
        client = OcCollabClient()
        
        progress = client.get_project_progress("test-project")
        
        assert progress is not None


if __name__ == "__main__":
    pytest.main([__file__, "-v", "--tb=short"])
