"""
存储策略基类
定义存储策略的抽象接口
"""
from abc import ABC, abstractmethod
from typing import Optional, Any, List
from pathlib import Path

from llama_index.core import VectorStoreIndex, StorageContext
from llama_index.core.schema import BaseNode

from src.types import OperationResult, StorageConfig


class StorageStrategy(ABC):
    """
    存储策略抽象基类
    
    使用策略模式，定义存储操作的统一接口，
    允许运行时切换不同的存储后端实现
    """
    
    def __init__(self, config: StorageConfig):
        """
        初始化存储策略
        
        Args:
            config: 存储配置
        """
        self.config = config
        self._storage_context: Optional[StorageContext] = None
    
    @abstractmethod
    def initialize(self) -> OperationResult:
        """
        初始化存储
        
        Returns:
            操作结果
        """
        pass
    
    @abstractmethod
    def build_index(self, nodes: List[BaseNode], show_progress: bool = True) -> Optional[VectorStoreIndex]:
        """
        构建向量索引
        
        Args:
            nodes: 文档节点列表
            show_progress: 是否显示进度
            
        Returns:
            向量索引实例或None
        """
        pass
    
    @abstractmethod
    def load_index(self) -> Optional[VectorStoreIndex]:
        """
        加载向量索引
        
        Returns:
            向量索引实例或None
        """
        pass
    
    @abstractmethod
    def persist(self, index: VectorStoreIndex) -> OperationResult:
        """
        持久化索引
        
        Args:
            index: 向量索引实例
            
        Returns:
            操作结果
        """
        pass
    
    @abstractmethod
    def delete(self) -> OperationResult:
        """
        删除存储
        
        Returns:
            操作结果
        """
        pass
    
    @abstractmethod
    def exists(self) -> bool:
        """
        检查存储是否存在
        
        Returns:
            是否存在
        """
        pass
    
    def get_storage_context(self) -> Optional[StorageContext]:
        """
        获取存储上下文
        
        Returns:
            存储上下文
        """
        return self._storage_context
    
    @property
    def backend_name(self) -> str:
        """获取后端名称"""
        return self.config.backend.value
