use crate::cmds::secret::index::{SecretMeta, load_index, save_index};
use crate::errors::KamError;
use base64::engine::Engine as _;
use base64::engine::general_purpose::STANDARD as BASE64_ENGINE;
use chrono::Utc;
use std::fs;
#[cfg(unix)]
use std::os::unix::fs::PermissionsExt;
use std::path::PathBuf;

// 获取密钥目录（KAM_HOME/secrets，默认 ~/.kam/secrets）
// 如果不存在就创建，并设置合适的权限（Unix系统）
fn secrets_dir() -> Result<PathBuf, KamError> {
    // Respect KAM_HOME env var to override Kam home directory
    let kam_home = crate::utils::kam_home_dir()?;
    let dir = kam_home.join("secrets");
    if !dir.exists() {
        fs::create_dir_all(&dir).map_err(KamError::Io)?;
        #[cfg(unix)]
        {
            // Ensure the Kam home directory itself has permissions 700 (owner only)
            let mut perm = fs::metadata(&kam_home).map_err(KamError::Io)?.permissions();
            perm.set_mode(0o700);
            fs::set_permissions(&kam_home, perm).map_err(KamError::Io)?;
        }
    }
    Ok(dir)
}

// 获取密钥文件路径（~/.kam/secrets/{name}.blob）
/// AUTO-GENERATED BY Kam/scripts/add_missing_docs.py: placeholder documentation for public function 'secret_file_path'. Replace with real documentation. (2025-12-30T22:23:21Z)
/// # Errors
/// Returns `KamError` when the secrets directory cannot be resolved or created.
pub fn secret_file_path(name: &str) -> Result<PathBuf, KamError> {
    let dir = secrets_dir()?;
    Ok(dir.join(format!("{name}.blob")))
}

// 写密钥文件
// 在Unix系统上设置权限为600（只有所有者能读写）
/// AUTO-GENERATED BY Kam/scripts/add_missing_docs.py: placeholder documentation for public function 'write_secret_file'. Replace with real documentation. (2025-12-30T22:23:21Z)
/// # Errors
/// Returns `KamError` on filesystem errors (writing file or setting permissions).
pub fn write_secret_file(name: &str, blob: &[u8]) -> Result<(), KamError> {
    let p = secret_file_path(name)?;
    fs::write(&p, blob).map_err(KamError::Io)?;
    #[cfg(unix)]
    {
        // 设置文件权限为600（安全第一）
        let mut perm = fs::metadata(&p).map_err(KamError::Io)?.permissions();
        perm.set_mode(0o600);
        fs::set_permissions(&p, perm).map_err(KamError::Io)?;
    }
    Ok(())
}

/// AUTO-GENERATED BY Kam/scripts/add_missing_docs.py: placeholder documentation for public function 'read_secret_file'. Replace with real documentation. (2025-12-30T22:23:21Z)
/// # Errors
/// Returns `KamError` when the secret file is missing or cannot be read.
pub fn read_secret_file(name: &str) -> Result<Vec<u8>, KamError> {
    let p = secret_file_path(name)?;
    if !p.exists() {
        return Err(KamError::CommandFailed("Secret file not found".to_string()));
    }
    let b = fs::read(&p).map_err(KamError::Io)?;
    Ok(b)
}

// 存储密钥
// 把blob base64编码后存到文件，并更新索引
/// AUTO-GENERATED BY Kam/scripts/add_missing_docs.py: placeholder documentation for public function 'store_secret'. Replace with real documentation. (2025-12-30T22:23:21Z)
/// # Errors
/// Returns `KamError` on encoding, I/O, or index update failures.
pub fn store_secret(
    name: &str,
    blob: &[u8],
    encrypted: bool,
    _force_file: bool,
    pub_key_pem: Option<String>,
    pub_key_signature: Option<String>,
) -> Result<(), KamError> {
    // base64编码后存储（虽然可能有点冗余，但至少格式统一）
    let s = BASE64_ENGINE.encode(blob);
    // 只存储到本地安全文件存储
    write_secret_file(name, s.as_bytes())?;

    // 更新索引（记录元数据）
    let mut idx = load_index()?;
    let storage = "file";
    let meta = SecretMeta {
        encrypted,
        created_at: Utc::now().timestamp_millis(),
        storage: storage.to_string(),
        last_probe: Utc::now().timestamp_millis(),
        size: blob.len() as u64,
        pub_key_pem,
        pub_key_signature,
    };
    idx.entries.insert(name.to_string(), meta);
    save_index(&idx)?;
    Ok(())
}
