"""
TurboEntityStore - 继承自 TurboEntity 的实体的配置存储抽象

所有继承 TurboEntity 的类（Agent, Character, Tool, LLMModel）的 CRUD 操作都通过此接口定义。
资源定位方式：belongToProjectId + name_id

此外包含：
- Agent 绑定管理（Character/Tool/Secret）
- Space 管理（通过 spaceName 定位）
"""

from abc import ABC, abstractmethod
from typing import Optional, List
from turbo_agent_core.schema.agents import Agent, Tool, Character, LLMModel
from turbo_agent_core.schema.basic import Space


class TurboEntityStore(ABC):
    """
    继承自 TurboEntity 的实体的配置存储抽象类。
    
    所有方法均支持 **kwargs 参数，用于实现侧传入鉴权信息（如 user_id, org_id 等）。
    资源定位方式：belongToProjectId + name_id 组合唯一确定一个主干资源。
    """

    # ========== Agent CRUD ==========
    @abstractmethod
    async def get_agent(
        self, 
        belong_to_project_id: str, 
        name_id: str, 
        version: Optional[str] = None, 
        **kwargs
    ) -> Optional[Agent]:
        """
        根据项目ID和name_id获取 Agent。

        Args:
            belong_to_project_id: 所属项目ID
            name_id: Agent 的名称标识（项目内唯一）
            version: 可选的版本号
            **kwargs: 实现侧可传入 user_id, org_id 等鉴权信息
        """
        pass

    @abstractmethod
    async def save_agent(self, agent: Agent, **kwargs) -> str:
        """
        保存 Agent，返回版本 ID。

        Args:
            agent: Agent 实例
            **kwargs: 实现侧可传入 user_id, org_id 等鉴权信息
        """
        pass

    @abstractmethod
    async def list_agents(
        self, 
        belong_to_project_id: str,
        skip: int = 0, 
        limit: int = 20, 
        **kwargs
    ) -> List[Agent]:
        """
        列出指定项目下的 Agents。

        Args:
            belong_to_project_id: 所属项目ID
            skip: 跳过的记录数
            limit: 返回的最大记录数
            **kwargs: 实现侧可传入 user_id, org_id 等鉴权信息
        """
        pass

    @abstractmethod
    async def delete_agent(
        self, 
        belong_to_project_id: str, 
        name_id: str, 
        **kwargs
    ) -> bool:
        """
        根据项目ID和name_id删除 Agent。

        Args:
            belong_to_project_id: 所属项目ID
            name_id: Agent 的名称标识
            **kwargs: 实现侧可传入 user_id, org_id 等鉴权信息
        """
        pass

    # ========== Agent 绑定管理 ==========
    @abstractmethod
    async def bind_agent_character(
        self, 
        agent_project_id: str,
        agent_name_id: str,
        character_project_id: str,
        character_name_id: str,
        **kwargs
    ) -> bool:
        """
        绑定 Character 到 Agent。

        Args:
            agent_project_id: Agent 所属项目ID
            agent_name_id: Agent 的 name_id
            character_project_id: Character 所属项目ID
            character_name_id: Character 的 name_id
            **kwargs: 实现侧可传入 user_id 等鉴权信息
        """
        pass

    @abstractmethod
    async def unbind_agent_character(
        self, 
        agent_project_id: str,
        agent_name_id: str,
        character_project_id: str,
        character_name_id: str,
        **kwargs
    ) -> bool:
        """
        解绑 Agent 的 Character。

        Args:
            agent_project_id: Agent 所属项目ID
            agent_name_id: Agent 的 name_id
            character_project_id: Character 所属项目ID
            character_name_id: Character 的 name_id
            **kwargs: 实现侧可传入 user_id 等鉴权信息
        """
        pass

    @abstractmethod
    async def bind_agent_tool(
        self, 
        agent_project_id: str,
        agent_name_id: str,
        tool_project_id: str,
        tool_name_id: str,
        **kwargs
    ) -> bool:
        """
        绑定 Tool 到 Agent。

        Args:
            agent_project_id: Agent 所属项目ID
            agent_name_id: Agent 的 name_id
            tool_project_id: Tool 所属项目ID
            tool_name_id: Tool 的 name_id
            **kwargs: 实现侧可传入 user_id 等鉴权信息
        """
        pass

    @abstractmethod
    async def unbind_agent_tool(
        self, 
        agent_project_id: str,
        agent_name_id: str,
        tool_project_id: str,
        tool_name_id: str,
        **kwargs
    ) -> bool:
        """
        解绑 Agent 的 Tool。

        Args:
            agent_project_id: Agent 所属项目ID
            agent_name_id: Agent 的 name_id
            tool_project_id: Tool 所属项目ID
            tool_name_id: Tool 的 name_id
            **kwargs: 实现侧可传入 user_id 等鉴权信息
        """
        pass

    @abstractmethod
    async def bind_agent_secret(
        self, 
        agent_project_id: str,
        agent_name_id: str,
        secret_id: str,
        **kwargs
    ) -> bool:
        """
        绑定 Secret 到 Agent。

        Args:
            agent_project_id: Agent 所属项目ID
            agent_name_id: Agent 的 name_id
            secret_id: Secret ID
            **kwargs: 实现侧可传入 user_id 等鉴权信息
        """
        pass

    @abstractmethod
    async def unbind_agent_secret(
        self, 
        agent_project_id: str,
        agent_name_id: str,
        secret_id: str,
        **kwargs
    ) -> bool:
        """
        解绑 Agent 的 Secret。

        Args:
            agent_project_id: Agent 所属项目ID
            agent_name_id: Agent 的 name_id
            secret_id: Secret ID
            **kwargs: 实现侧可传入 user_id 等鉴权信息
        """
        pass

    @abstractmethod
    async def list_agent_characters(
        self,
        agent_project_id: str,
        agent_name_id: str,
        **kwargs
    ) -> List[Character]:
        """
        列出 Agent 绑定的所有 Characters。

        Args:
            agent_project_id: Agent 所属项目ID
            agent_name_id: Agent 的 name_id
            **kwargs: 实现侧可传入 user_id 等鉴权信息
        """
        pass

    @abstractmethod
    async def list_agent_tools(
        self,
        agent_project_id: str,
        agent_name_id: str,
        **kwargs
    ) -> List[Tool]:
        """
        列出 Agent 绑定的所有 Tools。

        Args:
            agent_project_id: Agent 所属项目ID
            agent_name_id: Agent 的 name_id
            **kwargs: 实现侧可传入 user_id 等鉴权信息
        """
        pass

    # ========== Character CRUD ==========
    @abstractmethod
    async def get_character(
        self, 
        belong_to_project_id: str, 
        name_id: str, 
        version: Optional[str] = None, 
        **kwargs
    ) -> Optional[Character]:
        """
        根据项目ID和name_id获取 Character。

        Args:
            belong_to_project_id: 所属项目ID
            name_id: Character 的名称标识
            version: 可选的版本号
            **kwargs: 实现侧可传入 user_id, org_id 等鉴权信息
        """
        pass

    @abstractmethod
    async def save_character(self, character: Character, **kwargs) -> str:
        """
        保存 Character，返回版本 ID。

        Args:
            character: Character 实例
            **kwargs: 实现侧可传入 user_id, org_id 等鉴权信息
        """
        pass

    @abstractmethod
    async def list_characters(
        self, 
        belong_to_project_id: str,
        skip: int = 0, 
        limit: int = 20, 
        **kwargs
    ) -> List[Character]:
        """
        列出指定项目下的 Characters。

        Args:
            belong_to_project_id: 所属项目ID
            skip: 跳过的记录数
            limit: 返回的最大记录数
            **kwargs: 实现侧可传入 user_id, org_id 等鉴权信息
        """
        pass

    @abstractmethod
    async def delete_character(
        self, 
        belong_to_project_id: str, 
        name_id: str, 
        **kwargs
    ) -> bool:
        """
        根据项目ID和name_id删除 Character。

        Args:
            belong_to_project_id: 所属项目ID
            name_id: Character 的名称标识
            **kwargs: 实现侧可传入 user_id, org_id 等鉴权信息
        """
        pass

    # ========== Tool CRUD ==========
    @abstractmethod
    async def get_tool(
        self, 
        belong_to_project_id: str, 
        name_id: str, 
        version: Optional[str] = None, 
        **kwargs
    ) -> Optional[Tool]:
        """
        根据项目ID和name_id获取 Tool。

        Args:
            belong_to_project_id: 所属项目ID
            name_id: Tool 的名称标识
            version: 可选的版本号
            **kwargs: 实现侧可传入 user_id, org_id 等鉴权信息
        """
        pass

    @abstractmethod
    async def save_tool(self, tool: Tool, **kwargs) -> str:
        """
        保存 Tool，返回版本 ID。

        Args:
            tool: Tool 实例
            **kwargs: 实现侧可传入 user_id, org_id 等鉴权信息
        """
        pass

    @abstractmethod
    async def list_tools(
        self, 
        belong_to_project_id: str,
        skip: int = 0, 
        limit: int = 20, 
        **kwargs
    ) -> List[Tool]:
        """
        列出指定项目下的 Tools。

        Args:
            belong_to_project_id: 所属项目ID
            skip: 跳过的记录数
            limit: 返回的最大记录数
            **kwargs: 实现侧可传入 user_id, org_id 等鉴权信息
        """
        pass

    @abstractmethod
    async def delete_tool(
        self, 
        belong_to_project_id: str, 
        name_id: str, 
        **kwargs
    ) -> bool:
        """
        根据项目ID和name_id删除 Tool。

        Args:
            belong_to_project_id: 所属项目ID
            name_id: Tool 的名称标识
            **kwargs: 实现侧可传入 user_id, org_id 等鉴权信息
        """
        pass

    # ========== LLMModel CRUD ==========
    @abstractmethod
    async def get_model(
        self, 
        belong_to_project_id: str, 
        name_id: str, 
        version: Optional[str] = None, 
        **kwargs
    ) -> Optional[LLMModel]:
        """
        根据项目ID和name_id获取 LLMModel。

        Args:
            belong_to_project_id: 所属项目ID
            name_id: Model 的名称标识
            version: 可选的版本号
            **kwargs: 实现侧可传入 user_id, org_id 等鉴权信息
        """
        pass

    @abstractmethod
    async def save_model(self, model: LLMModel, **kwargs) -> str:
        """
        保存 LLMModel，返回版本 ID。

        Args:
            model: LLMModel 实例
            **kwargs: 实现侧可传入 user_id, org_id 等鉴权信息
        """
        pass

    @abstractmethod
    async def list_models(
        self, 
        belong_to_project_id: str,
        skip: int = 0, 
        limit: int = 20, 
        **kwargs
    ) -> List[LLMModel]:
        """
        列出指定项目下的 LLMModels。

        Args:
            belong_to_project_id: 所属项目ID
            skip: 跳过的记录数
            limit: 返回的最大记录数
            **kwargs: 实现侧可传入 user_id, org_id 等鉴权信息
        """
        pass

    @abstractmethod
    async def delete_model(
        self, 
        belong_to_project_id: str, 
        name_id: str, 
        **kwargs
    ) -> bool:
        """
        根据项目ID和name_id删除 LLMModel。

        Args:
            belong_to_project_id: 所属项目ID
            name_id: Model 的名称标识
            **kwargs: 实现侧可传入 user_id, org_id 等鉴权信息
        """
        pass

    # ========== Space 管理 ==========
    @abstractmethod
    async def get_space(self, space_name: str, **kwargs) -> Optional[Space]:
        """
        通过 spaceName 获取 Space 信息。

        Args:
            space_name: Space 名称标识
            **kwargs: 实现侧可传入 user_id, org_id 等鉴权信息
        """
        pass

    @abstractmethod
    async def create_space(self, space: Space, **kwargs) -> str:
        """
        创建 Space。

        Args:
            space: Space 实例
            **kwargs: 实现侧可传入 user_id, org_id 等鉴权信息
        """
        pass

    @abstractmethod
    async def update_space(
        self, 
        space_name: str, 
        space: Space, 
        **kwargs
    ) -> bool:
        """
        更新 Space（spaceName 不可变，只能更新其他字段）。

        Args:
            space_name: 原 Space 名称标识
            space: 新的 Space 数据
            **kwargs: 实现侧可传入 user_id, org_id 等鉴权信息
        """
        pass

    @abstractmethod
    async def delete_space(self, space_name: str, **kwargs) -> bool:
        """
        删除 Space。

        Args:
            space_name: Space 名称标识
            **kwargs: 实现侧可传入 user_id, org_id 等鉴权信息
        """
        pass

    @abstractmethod
    async def list_spaces(
        self, 
        space_type: Optional[str] = None,
        skip: int = 0, 
        limit: int = 20, 
        **kwargs
    ) -> List[Space]:
        """
        列出 Spaces。

        Args:
            space_type: 可选的 Space 类型过滤（USER/ORG）
            skip: 跳过的记录数
            limit: 返回的最大记录数
            **kwargs: 实现侧可传入 user_id, org_id 等鉴权信息
        """
        pass
