"""
Version API Client - 使用conf-man HTTP API
PM-Agent v2.0 - F-032

功能: 封装conf-man版本管理HTTP API调用
"""
import os
import logging
from typing import List, Dict, Any, Optional

logger = logging.getLogger(__name__)

try:
    import requests
except ImportError:
    requests = None


class VersionAPIClientError(Exception):
    """Version API Client异常"""
    pass


class VersionAPIClient:
    """版本管理HTTP API客户端"""
    
    DEFAULT_BASE_URL = "http://localhost:8002"
    
    def __init__(self, base_url: str = None, api_key: str = None, timeout: int = 30):
        """
        初始化VersionAPIClient
        
        Args:
            base_url: API服务地址，默认从环境变量CONF_MAN_API_URL获取
            api_key: API密钥，默认从环境变量CONF_MAN_API_KEY获取
            timeout: 请求超时时间
        """
        self.base_url = base_url or os.environ.get("CONF_MAN_API_URL", self.DEFAULT_BASE_URL)
        self.api_key = api_key or os.environ.get("CONF_MAN_API_KEY", "")
        self.timeout = timeout
        self._session = None
    
    def _get_session(self):
        """获取或创建requests session"""
        if self._session is None:
            self._session = requests.Session()
            if self.api_key:
                self._session.headers["X-API-Key"] = self.api_key
        return self._session
    
    def _request(self, method: str, endpoint: str, **kwargs) -> Dict[str, Any]:
        """发送HTTP请求"""
        if requests is None:
            raise VersionAPIClientError("requests library not installed")
        
        url = f"{self.base_url}{endpoint}"
        session = self._get_session()
        
        try:
            resp = session.request(method, url, timeout=self.timeout, **kwargs)
            resp.raise_for_status()
            return resp.json() if resp.content else {}
        except requests.exceptions.ConnectionError:
            raise VersionAPIClientError(f"Cannot connect to conf-man API at {self.base_url}. Please ensure conf-man API service is running.")
        except requests.exceptions.Timeout:
            raise VersionAPIClientError(f"Request to {url} timed out")
        except requests.exceptions.HTTPError as e:
            raise VersionAPIClientError(f"HTTP error: {e}")
    
    def _check_available(self):
        """检查API是否可用"""
        if requests is None:
            raise VersionAPIClientError("requests library not installed")
    
    def list_versions(self, status: Optional[str] = None, project: Optional[str] = None) -> List[Dict[str, Any]]:
        """
        列出版本
        
        Args:
            status: 过滤状态 (draft/released/deprecated)
            project: 项目名称
        
        Returns:
            版本列表
        """
        self._check_available()
        params = {}
        if status:
            params["status"] = status
        if project:
            params["project"] = project
        
        result = self._request('GET', '/api/v1/versions', params=params)
        if isinstance(result, list):
            return result
        return result.get('versions', [])
    
    def show_version(self, version: str) -> Dict[str, Any]:
        """
        显示版本详情
        
        Args:
            version: 版本号
        
        Returns:
            版本详情
        """
        self._check_available()
        return self._request('GET', f'/api/v1/versions/{version}')
    
    def register_version(
        self,
        version: str,
        manifest_path: Optional[str] = None,
        test_report_path: Optional[str] = None,
        project: Optional[str] = None
    ) -> Dict[str, Any]:
        """
        登记新版本
        
        Args:
            version: 版本号
            manifest_path: 版本清单文件路径
            test_report_path: 测试报告文件路径
            project: 项目名称
        
        Returns:
            登记结果
        """
        self._check_available()
        data = {
            "version": version,
            "project_id": project or "pm-agent"
        }
        if manifest_path:
            data["manifest_path"] = manifest_path
        if test_report_path:
            data["test_report_path"] = test_report_path
        
        return self._request('POST', '/api/v1/versions', json=data)
    
    def release_version(self, version: str) -> Dict[str, Any]:
        """
        发布版本
        
        Args:
            version: 版本号
        
        Returns:
            发布结果
        """
        self._check_available()
        return self._request('POST', f'/api/v1/versions/{version}/release')
    
    def rollback_version(self, version: str) -> Dict[str, Any]:
        """
        回滚版本
        
        Args:
            version: 版本号
        
        Returns:
            回滚结果
        """
        self._check_available()
        return self._request('POST', f'/api/v1/versions/{version}/rollback')
    
    def get_dependencies(self, version: str) -> List[Dict[str, Any]]:
        """
        获取版本依赖
        
        Args:
            version: 版本号
        
        Returns:
            依赖列表
        """
        self._check_available()
        result = self.show_version(version)
        if isinstance(result, dict):
            manifest = result.get("manifest", {})
            return manifest.get("dependencies", [])
        return []
    
    def list_projects(self) -> List[Dict[str, Any]]:
        """
        列出项目
        
        Returns:
            项目列表
        """
        self._check_available()
        result = self._request('GET', '/api/v1/projects')
        if isinstance(result, list):
            return result
        return result.get('projects', [])
    
    def show_project(self, name: str) -> Dict[str, Any]:
        """
        显示项目详情
        
        Args:
            name: 项目名称
        
        Returns:
            项目详情
        """
        self._check_available()
        return self._request('GET', f'/api/v1/projects/{name}')
    
    def export_manifest(self, version: str, output_path: str) -> Dict[str, Any]:
        """
        导出版本清单
        
        Args:
            version: 版本号
            output_path: 输出文件路径
        
        Returns:
            导出结果
        """
        self._check_available()
        return self._request('POST', '/api/v1/export', json={"version": version, "output": output_path})
    
    def import_manifest(self, input_path: str) -> Dict[str, Any]:
        """
        导入版本清单
        
        Args:
            input_path: 输入文件路径
        
        Returns:
            导入结果
        """
        self._check_available()
        return self._request('POST', '/api/v1/import', json={"input": input_path})
    
    def get_current_version(self) -> Optional[str]:
        """
        获取当前版本
        
        Returns:
            当前版本号，如果没有则返回None
        """
        self._check_available()
        try:
            result = self._request('GET', '/api/v1/versions/current')
            return result.get("version")
        except VersionAPIClientError:
            return None


_version_api_client = None


def get_version_api_client() -> VersionAPIClient:
    """获取全局VersionAPIClient实例"""
    global _version_api_client
    if _version_api_client is None:
        _version_api_client = VersionAPIClient()
    return _version_api_client


def set_version_api_client(client: VersionAPIClient):
    """设置全局VersionAPIClient实例（用于测试）"""
    global _version_api_client
    _version_api_client = client
