"""
版本管理E2E测试场景
PM-Agent v2.0 - T-003 E2E测试场景设计
"""
import pytest
import sys
from pathlib import Path
from unittest.mock import Mock, patch, MagicMock

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


class TestVersionListFlow:
    """版本列表查询E2E场景"""

    @pytest.fixture
    def e2e_setup(self):
        """E2E测试设置"""
        with patch('backend.services.version_service.VersionClient') as mock:
            client = MagicMock()
            client.list_versions.return_value = [
                {
                    "version": "v1.0.0",
                    "status": "released",
                    "registered_at": "2026-01-15T10:00:00Z"
                },
                {
                    "version": "v1.1.0", 
                    "status": "draft",
                    "registered_at": "2026-02-01T10:00:00Z"
                }
            ]
            mock.return_value = client
            yield {"client": client, "mock": mock}

    def test_version_list_flow(self, e2e_setup):
        """场景: 用户查询版本列表"""
        from backend.services.version_service import VersionClient
        
        client = VersionClient()
        versions = client.list_versions()
        
        assert len(versions) == 2
        assert versions[0]["version"] == "v1.0.0"
        assert versions[0]["status"] == "released"

    def test_version_list_filter_released(self, e2e_setup):
        """场景: 用户筛选已发布版本"""
        from backend.services.version_service import VersionClient
        
        client = VersionClient()
        versions = client.list_versions()
        released = [v for v in versions if v["status"] == "released"]
        
        assert len(released) == 1
        assert released[0]["version"] == "v1.0.0"


class TestVersionDetailFlow:
    """版本详情查询E2E场景"""

    @pytest.fixture
    def e2e_setup(self):
        """E2E测试设置"""
        with patch('backend.services.version_service.VersionClient') as mock:
            client = MagicMock()
            client.show_version.return_value = {
                "version": "v1.0.0",
                "status": "released",
                "registered_at": "2026-01-15T10:00:00Z",
                "commit_hash": "abc123def456",
                "manifest": {
                    "files": [
                        {"path": "src/main.py", "size": 1024},
                        {"path": "src/config.py", "size": 512}
                    ],
                    "dependencies": [
                        {"name": "pyyaml", "version": ">=5.4"}
                    ]
                },
                "test_report": {
                    "passed": 150,
                    "failed": 0,
                    "errors": 0,
                    "duration": 120.5
                }
            }
            mock.return_value = client
            yield {"client": client, "mock": mock}

    def test_version_detail_flow(self, e2e_setup):
        """场景: 用户查看版本详情"""
        from backend.services.version_service import VersionClient
        
        client = VersionClient()
        detail = client.show_version("v1.0.0")
        
        assert detail["version"] == "v1.0.0"
        assert detail["status"] == "released"
        assert detail["commit_hash"] == "abc123def456"
        assert len(detail["manifest"]["files"]) == 2

    def test_version_dependencies_flow(self, e2e_setup):
        """场景: 用户查看版本依赖"""
        from backend.services.version_service import VersionClient
        
        client = VersionClient()
        detail = client.show_version("v1.0.0")
        
        deps = detail["manifest"]["dependencies"]
        assert len(deps) == 1
        assert deps[0]["name"] == "pyyaml"


class TestVersionErrorFlows:
    """异常场景E2E测试"""

    @pytest.fixture
    def e2e_setup_errors(self):
        """异常场景测试设置"""
        with patch('backend.services.version_service.VersionClient') as mock:
            client = MagicMock()
            client.show_version.side_effect = Exception("Version not found")
            mock.return_value = client
            yield {"client": client, "mock": mock}

    def test_version_not_found_flow(self, e2e_setup_errors):
        """场景: 用户查询不存在的版本"""
        from backend.services.version_service import VersionClient
        
        client = VersionClient()
        
        with pytest.raises(Exception) as exc_info:
            client.show_version("v999.0.0")
        
        assert "not found" in str(exc_info.value).lower()

    def test_conf_man_unavailable_flow(self):
        """场景: conf-man服务不可用"""
        with patch('backend.services.version_service.subprocess.run', side_effect=FileNotFoundError):
            from backend.services.version_service import VersionClient
            
            client = VersionClient()
            
            with pytest.raises(Exception) as exc_info:
                client.list_versions()
            
            assert "conf-man" in str(exc_info.value).lower() or "not found" in str(exc_info.value).lower()


class TestConfManPathFlows:
    """ConfMan路径查询E2E场景"""

    @pytest.fixture
    def e2e_setup_conf_man(self):
        """ConfMan测试设置"""
        with patch('backend.integrations.conf_man_client.ConfManProvider') as mock:
            provider = MagicMock()
            provider.get_data_dir.return_value = "/data"
            provider.get_config_dir.return_value = "/config"
            provider.get_log_dir.return_value = "/logs"
            provider.get_todo_db_path.return_value = "/data/todos.db"
            provider.get_environment.return_value = "production"
            provider.is_test_mode.return_value = False
            mock.return_value = provider
            yield {"provider": provider, "mock": mock}

    def test_get_all_paths_flow(self, e2e_setup_conf_man):
        """场景: 用户获取所有路径配置"""
        from backend.integrations.conf_man_client import ConfManClient
        
        client = ConfManClient()
        
        assert client.get_data_dir() == "/data"
        assert client.get_config_dir() == "/config"
        assert client.get_log_dir() == "/logs"
        assert client.get_todo_db_path() == "/data/todos.db"

    def test_environment_check_flow(self, e2e_setup_conf_man):
        """场景: 用户检查运行环境"""
        from backend.integrations.conf_man_client import ConfManClient
        
        client = ConfManClient()
        
        assert client.get_environment() == "production"
        assert client.is_test_mode() is False


class TestEndToEndVersionWorkflow:
    """完整版本管理工作流E2E"""

    def test_complete_version_workflow(self):
        """场景: 完整版本管理工作流"""
        with patch('backend.services.version_service.VersionClient') as version_mock, \
             patch('backend.integrations.conf_man_client.ConfManProvider') as conf_man_mock:
            
            version_client = MagicMock()
            version_client.list_versions.return_value = [
                {"version": "v1.0.0", "status": "draft"}
            ]
            version_client.show_version.return_value = {
                "version": "v1.0.0",
                "status": "draft",
                "test_report": {"passed": 100, "failed": 0}
            }
            version_client.release_version.return_value = {"status": "success"}
            version_mock.return_value = version_client
            
            conf_man_mock.return_value.get_environment.return_value = "test"
            conf_man_mock.return_value.is_test_mode.return_value = True
            
            from backend.services.version_service import VersionClient
            from backend.integrations.conf_man_client import ConfManClient
            
            vc = VersionClient()
            cc = ConfManClient()
            
            versions = vc.list_versions()
            assert len(versions) >= 0
            
            if versions:
                detail = vc.show_version(versions[0]["version"])
                assert detail is not None
                
                if detail.get("test_report", {}).get("failed", 1) == 0:
                    result = vc.release_version(versions[0]["version"])
                    assert result["status"] == "success"
            
            env = cc.get_environment()
            assert env is not None
