"""RoboDock Client - High-level interface for RoboDock SDK."""

from typing import Optional
from .actions import RoboDockActions


class RoboDockClient:
    """RoboDock客户端，提供便捷的高层API。"""

    @staticmethod
    def _validate_non_empty(name: str, value: Optional[str]) -> None:
        if value is None:
            return
        if not isinstance(value, str) or not value.strip():
            raise ValueError(f"{name} must be a non-empty string when provided")

    def __init__(
        self,
        s3_endpoint: Optional[str] = None,
        s3_access_key: Optional[str] = None,
        s3_secret_key: Optional[str] = None,
        api_url: Optional[str] = None,
        bucket_name: Optional[str] = None,
        region_name: Optional[str] = None
    ):
        """初始化RoboDock客户端。
        
        Args:
            s3_endpoint: S3存储服务端点
            s3_access_key: S3访问密钥
            s3_secret_key: S3密钥
            api_url: RoboDock API URL
            bucket_name: S3存储桶名称
            region_name: S3区域名称
        """
        self._validate_non_empty("s3_endpoint", s3_endpoint)
        self._validate_non_empty("s3_access_key", s3_access_key)
        self._validate_non_empty("s3_secret_key", s3_secret_key)
        self._validate_non_empty("api_url", api_url)
        self._validate_non_empty("bucket_name", bucket_name)
        self._validate_non_empty("region_name", region_name)

        kwargs = {}
        if s3_endpoint:
            kwargs['s3_endpoint'] = s3_endpoint
        if s3_access_key:
            kwargs['s3_access_key'] = s3_access_key
        if s3_secret_key:
            kwargs['s3_secret_key'] = s3_secret_key
        if api_url:
            kwargs['api_url'] = api_url
        if bucket_name:
            kwargs['bucket_name'] = bucket_name
        if region_name:
            kwargs['region_name'] = region_name
            
        self.actions = RoboDockActions(**kwargs)

    def get_dataset(self, uuid: str):
        """获取数据集信息。
        
        Args:
            uuid: 数据集UUID
            
        Returns:
            数据集信息
        """
        return self.actions.get_dataset_info(uuid)

    def get_data(self, uuid: str):
        """获取单条数据信息。
        
        Args:
            uuid: 数据UUID
            
        Returns:
            数据信息
        """
        return self.actions.get_singledata_info(uuid)

    def get_run(self, unique_name: str, unique_type: str = "uuid"):
        """获取运行任务信息。
        
        Args:
            unique_name: 任务唯一标识
            unique_type: 标识类型
            
        Returns:
            任务信息
        """
        return self.actions.get_run_info(unique_name, unique_type)

    def download_dataset(self, data_name: str, uuid: str, dirname: str = "singledata"):
        """下载数据集。
        
        Args:
            data_name: 数据文件名
            uuid: 数据UUID
            dirname: S3目录名
            
        Returns:
            解压后的本地路径
        """
        return self.actions.download_data(data_name, uuid, dirname)

    def download_checkpoint(self, online_path: str, local_path: str):
        """下载检查点。
        
        Args:
            online_path: S3路径
            local_path: 本地路径
            
        Returns:
            解压后的路径
        """
        return self.actions.download_checkpoint(online_path, local_path)

    def upload_model(self, outdir_path: str, upload_path: str):
        """上传模型。
        
        Args:
            outdir_path: 本地输出目录
            upload_path: S3上传路径
            
        Returns:
            S3对象键
        """
        return self.actions.upload_data(outdir_path, upload_path)

    def upload_model_async(self, outdir_path: str, upload_path: str):
        """异步上传模型。

        Args:
            outdir_path: 本地输出目录
            upload_path: S3上传路径

        Returns:
            Future对象或None（队列已满）
        """
        return self.actions.upload_data_async(outdir_path, upload_path)

    def upload_checkpoint_async(
        self,
        *,
        outdir_path: str,
        upload_path: str,
        run_unique_name: str,
        unique_type: str = "unique_name",
        run_field: str = "check_point_path",
    ):
        """异步上传checkpoint并更新run。

        Args:
            outdir_path: 本地checkpoint目录
            upload_path: S3上传路径
            run_unique_name: 运行唯一标识
            unique_type: 标识类型
            run_field: 写回run的字段名

        Returns:
            Future对象或None（队列已满）
        """
        return self.actions.upload_checkpoint_async(
            outdir_path=outdir_path,
            upload_path=upload_path,
            run_unique_name=run_unique_name,
            unique_type=unique_type,
            run_field=run_field,
        )

    def update_run_status(self, unique_name: str, status: str, **kwargs):
        """更新任务状态。
        
        Args:
            unique_name: 任务唯一标识
            status: 状态（processing/success/failed）
            **kwargs: 其他更新字段（start_time, finish_time, fail_info等）
            
        Returns:
            HTTP状态码
        """
        body = {"status": status, **kwargs}
        return self.actions.update_run(unique_name, body, unique_type="unique_name")

    def update_singledata(self, uuid: str, checker_result: str, checker_info: str):
        """更新单条数据的检查结果。
        
        Args:
            uuid: 数据UUID
            checker_result: 检查结果
            checker_info: 检查信息
            
        Returns:
            HTTP状态码
        """
        return self.actions.update_singledata(uuid, checker_result, checker_info)
