"""
回归测试 - PM-Agent v1.2 核心模块
验证v2.0更新不影响现有功能
"""
import pytest
import sys
from pathlib import Path
from unittest.mock import Mock, patch, MagicMock

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


class TestLLMServiceRegression:
    """回归测试: LLM服务"""

    @patch('backend.integrations.siliconflow_client.requests.post')
    def test_llm_api_call(self, mock_post):
        """RT-001: 测试LLM API调用"""
        mock_response = Mock()
        mock_response.status_code = 200
        mock_response.json.return_value = {
            "choices": [{"message": {"content": "test response"}}]
        }
        mock_post.return_value = mock_response

        from backend.integrations.siliconflow_client import SiliconFlowClient
        client = SiliconFlowClient(api_key="test-key")
        
        with patch.object(client, 'chat', return_value={"choices": [{"message": {"content": "test"}}]}):
            result = client.chat("test prompt")
            assert "choices" in result or "message" in result

    def test_llm_client_init(self):
        """RT-002: 测试LLM客户端初始化"""
        from backend.integrations.siliconflow_client import SiliconFlowClient
        
        client = SiliconFlowClient(api_key="test-key-123")
        assert client.api_key == "test-key-123"


class TestDocumentFetcherRegression:
    """回归测试: 文档获取服务"""

    @patch('pathlib.Path.glob')
    def test_document_glob_pattern(self, mock_glob):
        """RT-003: 测试文档glob模式"""
        mock_glob.return_value = [Path("test.pdf"), Path("test.docx")]
        
        from backend.services.document_fetcher import DocumentFetcher
        fetcher = DocumentFetcher()
        
        result = list(Path(".").glob("*.pdf"))
        assert len(result) >= 0

    def test_document_fetcher_init(self):
        """RT-004: 测试文档获取器初始化"""
        from backend.services.document_fetcher import DocumentFetcher
        
        fetcher = DocumentFetcher()
        assert fetcher is not None


class TestGitServiceRegression:
    """回归测试: Git服务"""

    @patch('subprocess.run')
    def test_git_command_execution(self, mock_run):
        """RT-005: 测试Git命令执行"""
        mock_run.return_value = Mock(returncode=0, stdout="main")
        
        from backend.services.git_service import GitService
        service = GitService(".")
        
        with patch.object(service, 'run_command', return_value=Mock(returncode=0, stdout="main")):
            result = service.run_command(["git", "status"])
            assert result.returncode == 0

    def test_git_service_init(self):
        """RT-006: 测试Git服务初始化"""
        from backend.services.git_service import GitService
        
        service = GitService(".")
        assert service.repo_path == "."


class TestStatusFeedbackRegression:
    """回归测试: 状态反馈服务"""

    @patch('backend.services.status_feedback_service.json.load')
    def test_status_feedback_load(self, mock_load):
        """RT-007: 测试状态反馈加载"""
        mock_load.return_value = {"test-id": {"status": "pending"}}
        
        from backend.services.status_feedback_service import StatusFeedbackService
        
        service = StatusFeedbackService()
        with patch.object(service, '_load_status', return_value={"test-id": {"status": "pending"}}):
            result = service._load_status()
            assert "test-id" in result

    def test_status_feedback_init(self):
        """RT-008: 测试状态反馈初始化"""
        from backend.services.status_feedback_service import StatusFeedbackService
        
        service = StatusFeedbackService()
        assert service is not None


class TestClassifierRegression:
    """回归测试: 分类器服务"""

    def test_classifier_init(self):
        """RT-009: 测试分类器初始化"""
        from backend.services.classifier_service import ClassifierService
        
        service = ClassifierService()
        assert service is not None

    def test_classifier_empty_config(self):
        """RT-010: 测试空配置处理"""
        from backend.services.classifier_service import ClassifierService
        
        service = ClassifierService()
        
        with patch.object(service, 'classify', return_value={"category": "unknown"}):
            result = service.classify("")
            assert "category" in result


class TestProgressServiceRegression:
    """回归测试: 进度服务"""

    def test_progress_service_init(self):
        """RT-011: 测试进度服务初始化"""
        from backend.services.progress_service import ProgressService
        
        service = ProgressService()
        assert service is not None

    def test_progress_tracking(self):
        """RT-012: 测试进度跟踪"""
        from backend.services.progress_service import ProgressService
        
        service = ProgressService()
        
        with patch.object(service, 'update', return_value=True):
            result = service.update("task-1", 50)
            assert result is True or result is not None


class TestProjectServiceRegression:
    """回归测试: 项目服务"""

    def test_project_service_init(self):
        """RT-013: 测试项目服务初始化"""
        from backend.services.project_service import ProjectService
        
        service = ProjectService()
        assert service is not None

    def test_project_operations(self):
        """RT-014: 测试项目操作"""
        from backend.services.project_service import ProjectService
        
        service = ProjectService()
        
        with patch.object(service, 'get_projects', return_value=[]):
            result = service.get_projects()
            assert isinstance(result, list)


class TestOCCollabClientRegression:
    """回归测试: oc-collab客户端"""

    @patch('requests.post')
    def test_oc_collab_connection(self, mock_post):
        """RT-015: 测试oc-collab连接"""
        mock_response = Mock()
        mock_response.status_code = 200
        mock_response.json.return_value = {"status": "ok"}
        mock_post.return_value = mock_response

        from backend.services.oc_collab_client import OCCollabClient
        client = OCCollabClient()
        
        assert client is not None

    def test_oc_collab_init(self):
        """RT-016: 测试oc-collab客户端初始化"""
        from backend.services.oc_collab_client import OCCollabClient
        
        client = OCCollabClient()
        assert client is not None


class TestConfManClientRegression:
    """回归测试: ConfManClient (v2.0新增模块)"""

    def test_conf_man_import_error(self):
        """RT-017: 测试模块导入错误处理"""
        from backend.integrations.conf_man_client import ConfManClient, _set_conf_man_classes

        _set_conf_man_classes(None, None)

        with patch('builtins.__import__', side_effect=ImportError):
            client = ConfManClient()
            assert client._provider is None

    def test_conf_man_provider_not_available(self):
        """RT-018: 测试provider不可用"""
        from backend.integrations.conf_man_client import ConfManClient, _set_conf_man_classes

        mock_provider = Mock()
        mock_provider.get_data_dir.side_effect = Exception("Provider error")

        _set_conf_man_classes(mock_provider, None)

        try:
            client = ConfManClient()
            result = client.get_data_dir()
            assert result is not None
        finally:
            _set_conf_man_classes(None, None)


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