use anyhow::{anyhow, bail, Context, Result};
use clap::Args;
use colored::*;
use qdrant_client::qdrant::{Filter, PointsSelector, points_selector::PointsSelectorOneOf};
use std::{sync::Arc, path::PathBuf};
use super::helpers::{get_collection_name};
use log;
use crate::config::{self, AppConfig};
use crate::vectordb::qdrant_client_trait::QdrantClientTrait;
use std::fmt::Debug;
#[derive(Args, Debug)]
#[derive(Clone)]
pub struct ClearRepoArgs {
#[arg(short, long)]
pub name: Option<String>,
#[arg(short, long, default_value_t = false)]
pub yes: bool,
}
pub async fn handle_repo_clear<C>(
args: ClearRepoArgs,
config: &mut AppConfig,
client: Arc<C>,
_override_path: Option<&PathBuf>,
) -> Result<()>
where
C: QdrantClientTrait + Send + Sync + 'static,
{
let repo_name = match args.name.as_ref().or(config.active_repository.as_ref()) {
Some(name) => name.clone(),
None => bail!("No active repository set and no repository name provided."),
};
let repo_config_index = config
.repositories
.iter()
.position(|r| r.name == repo_name)
.ok_or_else(|| anyhow!("Configuration for repository '{}' not found.", repo_name))?;
println!(
"{}",
format!(
"Preparing to clear the index for repository '{}'. This will remove all indexed data for this repository.",
repo_name.cyan()
).yellow()
);
println!("{}", "This action CANNOT be undone.".red().bold());
if !args.yes {
println!("Are you sure you want to continue? (yes/No)");
let mut confirmation = String::new();
std::io::stdin().read_line(&mut confirmation)
.context("Failed to read confirmation input")?;
if confirmation.trim().to_lowercase() != "yes" {
println!("Operation cancelled.");
return Ok(());
}
}
let collection_name = get_collection_name(&repo_name);
match client.collection_exists(collection_name.clone()).await {
Ok(exists) => {
if !exists {
log::warn!("Collection '{}' does not exist. Nothing to clear.", collection_name);
return Ok(()); }
}
Err(e) => {
return Err(anyhow!("Failed to check existence of collection '{}': {}", collection_name, e));
}
}
println!("Deleting all points from collection '{}'...", collection_name.cyan());
let selector = PointsSelector {
points_selector_one_of: Some(PointsSelectorOneOf::Filter(Filter {
must: vec![],
should: vec![],
must_not: vec![],
min_should: None
}))
};
client.delete_points_blocking(&collection_name, &selector).await?;
let repo_config_mut = &mut config.repositories[repo_config_index];
repo_config_mut.last_synced_commits.clear();
repo_config_mut.indexed_languages = None;
config::save_config(config, _override_path)
.context("Failed to save config after clearing repository index")?;
println!(
"{}",
format!(
"Successfully cleared index and sync status for repository '{}'.",
repo_name.cyan()
).green()
);
Ok(())
}