"""
VersionClient 单元测试
PM-Agent v2.0 - F-032 集成测试

依赖: conf-man 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.parent))


class TestVersionClient:
    """VersionClient 测试类"""

    @pytest.fixture
    def mock_conf_man(self):
        """Mock conf-man CLI调用"""
        with patch('backend.services.version_service.subprocess') as mock:
            yield mock

    @pytest.fixture
    def version_client(self, mock_conf_man):
        """创建 VersionClient 实例"""
        from backend.services.version_service import VersionClient
        return VersionClient()

    def test_list_versions_empty(self, version_client, mock_conf_man):
        """测试列出版本 - 无版本"""
        mock_result = MagicMock()
        mock_result.returncode = 0
        mock_result.stdout = "[]"
        mock_conf_man.run.return_value = mock_result

        result = version_client.list_versions()
        assert result == []
        mock_conf_man.run.assert_called()

    def test_list_versions_with_data(self, version_client, mock_conf_man):
        """测试列出版本 - 有数据"""
        mock_result = MagicMock()
        mock_result.returncode = 0
        mock_result.stdout = '''[
            {"version": "v1.0.0", "status": "released", "registered_at": "2026-01-01T00:00:00Z"},
            {"version": "v1.1.0", "status": "draft", "registered_at": "2026-02-01T00:00:00Z"}
        ]'''
        mock_conf_man.run.return_value = mock_result

        result = version_client.list_versions()
        assert len(result) == 2
        assert result[0]["version"] == "v1.0.0"

    def test_show_version(self, version_client, mock_conf_man):
        """测试版本详情"""
        mock_result = MagicMock()
        mock_result.returncode = 0
        mock_result.stdout = '''{
            "version": "v1.0.0",
            "status": "released",
            "registered_at": "2026-01-01T00:00:00Z",
            "commit_hash": "abc123",
            "manifest": {"files": []},
            "test_report": {"passed": 100, "failed": 0}
        }'''
        mock_conf_man.run.return_value = mock_result

        result = version_client.show_version("v1.0.0")
        assert result["version"] == "v1.0.0"
        assert result["status"] == "released"

    def test_register_version(self, version_client, mock_conf_man):
        """测试登记版本"""
        mock_result = MagicMock()
        mock_result.returncode = 0
        mock_result.stdout = "Version v1.2.0 registered successfully"
        mock_conf_man.run.return_value = mock_result

        result = version_client.register_version(
            "v1.2.0",
            manifest_path="/path/to/manifest.yaml",
            test_report_path="/path/to/test_report.yaml"
        )
        assert result["status"] == "success"

    def test_release_version(self, version_client, mock_conf_man):
        """测试发布版本"""
        mock_result = MagicMock()
        mock_result.returncode = 0
        mock_result.stdout = "Version v1.0.0 released successfully"
        mock_conf_man.run.return_value = mock_result

        result = version_client.release_version("v1.0.0")
        assert result["status"] == "success"

    def test_get_dependencies(self, version_client, mock_conf_man):
        """测试获取依赖"""
        mock_result = MagicMock()
        mock_result.returncode = 0
        mock_result.stdout = '''[
            {"name": "pyyaml", "version": ">=5.4"},
            {"name": "click", "version": ">=8.0"}
        ]'''
        mock_conf_man.run.return_value = mock_result

        result = version_client.get_dependencies("v1.0.0")
        assert len(result) == 2

    def test_list_projects(self, version_client, mock_conf_man):
        """测试项目列表"""
        mock_result = MagicMock()
        mock_result.returncode = 0
        mock_result.stdout = '''[
            {"name": "pm-agent", "version": "v1.2.0"},
            {"name": "oc-collab", "version": "v2.4.0"}
        ]'''
        mock_conf_man.run.return_value = mock_result

        result = version_client.list_projects()
        assert len(result) == 2

    def test_cli_error_handling(self, version_client, mock_conf_man):
        """测试CLI错误处理"""
        mock_result = MagicMock()
        mock_result.returncode = 1
        mock_result.stderr = "Version not found"
        mock_conf_man.run.return_value = mock_result

        with pytest.raises(Exception) as exc_info:
            version_client.show_version("v999.0.0")
        assert "Version not found" in str(exc_info.value)

    def test_timeout_handling(self, version_client, mock_conf_man):
        """测试超时处理"""
        import subprocess
        mock_conf_man.run.side_effect = subprocess.TimeoutExpired("cmd", 30)

        with pytest.raises(Exception) as exc_info:
            version_client.list_versions()
        assert "timeout" in str(exc_info.value).lower()


class TestVersionClientIntegration:
    """VersionClient 集成测试"""

    @pytest.fixture
    def real_version_client(self):
        """创建真实 VersionClient"""
        from backend.services.version_service import VersionClient
        return VersionClient()

    def test_real_list_versions(self, real_version_client):
        """测试真实列出版本"""
        try:
            result = real_version_client.list_versions()
            assert isinstance(result, list)
        except Exception as e:
            pytest.skip(f"conf-man not available: {e}")

    def test_real_show_version(self, real_version_client):
        """测试真实版本详情"""
        try:
            versions = real_version_client.list_versions()
            if versions:
                result = real_version_client.show_version(versions[0]["version"])
                assert result is not None
            else:
                pytest.skip("No versions available")
        except Exception as e:
            pytest.skip(f"conf-man not available: {e}")
