//! Storage module for persisting and loading indexes.
//!
//! This module provides abstractions for storing workspace indexes,
//! document metadata, and embeddings to disk.

mod disk;
mod metadata;

pub use disk::DiskStorage;
pub use metadata::WorkspaceMetadata;

use std::path::PathBuf;

use crate::error::Result;
use crate::types::{Chunk, Document, WorkspaceId, WorkspaceStats};

/// Trait for storage backends.
pub trait Storage: Send + Sync {
    /// Initialize storage for a workspace.
    fn init_workspace(&self, workspace_id: &WorkspaceId, root_path: &PathBuf) -> Result<()>;

    /// Check if a workspace exists.
    fn workspace_exists(&self, workspace_id: &WorkspaceId) -> bool;

    /// Load workspace metadata.
    fn load_workspace_metadata(&self, workspace_id: &WorkspaceId) -> Result<WorkspaceMetadata>;

    /// Save workspace metadata.
    fn save_workspace_metadata(
        &self,
        workspace_id: &WorkspaceId,
        metadata: &WorkspaceMetadata,
    ) -> Result<()>;

    /// Save documents for a workspace.
    fn save_documents(&self, workspace_id: &WorkspaceId, documents: &[Document]) -> Result<()>;

    /// Load all documents for a workspace.
    fn load_documents(&self, workspace_id: &WorkspaceId) -> Result<Vec<Document>>;

    /// Save chunks for a workspace.
    fn save_chunks(&self, workspace_id: &WorkspaceId, chunks: &[Chunk]) -> Result<()>;

    /// Load all chunks for a workspace.
    fn load_chunks(&self, workspace_id: &WorkspaceId) -> Result<Vec<Chunk>>;

    /// Save embeddings for chunks.
    fn save_embeddings(
        &self,
        workspace_id: &WorkspaceId,
        embeddings: &[(String, Vec<f32>)], // (chunk_id, embedding)
    ) -> Result<()>;

    /// Load embeddings for a workspace.
    fn load_embeddings(&self, workspace_id: &WorkspaceId) -> Result<Vec<(String, Vec<f32>)>>;

    /// Get the path to the tantivy index directory.
    fn tantivy_index_path(&self, workspace_id: &WorkspaceId) -> PathBuf;

    /// Get the path to the vector index.
    fn vector_index_path(&self, workspace_id: &WorkspaceId) -> PathBuf;

    /// Delete a workspace and all its data.
    fn delete_workspace(&self, workspace_id: &WorkspaceId) -> Result<()>;

    /// List all stored workspaces.
    fn list_workspaces(&self) -> Result<Vec<WorkspaceId>>;

    /// Get workspace statistics.
    fn get_workspace_stats(&self, workspace_id: &WorkspaceId) -> Result<WorkspaceStats>;

    /// Flush any pending writes to disk.
    fn flush(&self) -> Result<()>;
}

/// Options for storage operations.
#[derive(Debug, Clone)]
pub struct StorageOptions {
    /// Use memory-mapped files where possible.
    pub use_mmap: bool,
    /// Compress data on disk.
    pub compress: bool,
    /// Buffer size for writes.
    pub buffer_size: usize,
}

impl Default for StorageOptions {
    fn default() -> Self {
        Self {
            use_mmap: true,
            compress: true,
            buffer_size: 64 * 1024, // 64KB
        }
    }
}
