use std::io::IsTerminal;
use anyhow::Context;
use clap::Parser;
use cruftkill::cli::CliArgs;
use cruftkill::tui;
#[tokio::main(flavor = "multi_thread")]
async fn main() -> anyhow::Result<()> {
let args = CliArgs::parse();
if let Some(unknown) = args.unknown_profile() {
anyhow::bail!("unknown profile: {unknown}. Run `cft --help` for the list.");
}
let no_tui = args.no_tui || !std::io::stdout().is_terminal();
if no_tui { run_no_tui(args).await.context("no-tui mode failed") } else { tui::run(args).await }
}
async fn run_no_tui(args: CliArgs) -> anyhow::Result<()> {
use cruftkill::core::{risk, scanner, size, types::ScanOptions};
let root = args.root_path()?;
let targets = args.resolved_targets();
let opts = ScanOptions {
targets: targets.clone(),
exclude: args.exclude.clone(),
sort_by: Some(args.sort.into()),
perform_risk_analysis: !args.no_risk,
};
let home = std::env::var("HOME").or_else(|_| std::env::var("USERPROFILE")).ok();
let home_path = home.as_deref().map(std::path::Path::new);
let mut handle = scanner::start_scan(root.clone(), opts);
while let Some(found) = handle.results.recv().await {
let size_bytes = size::get_folder_size(found.path.clone()).await.unwrap_or(0);
let risk_analysis =
if args.no_risk { None } else { Some(risk::analyze_with_home(&found.path, home_path)) };
let modified = std::fs::metadata(&found.path)
.and_then(|m| m.modified())
.ok()
.and_then(|t| t.duration_since(std::time::UNIX_EPOCH).ok())
.map(|d| d.as_secs());
let line = serde_json::json!({
"path": found.path,
"size_bytes": size_bytes,
"is_sensitive": risk_analysis.as_ref().map(|r| r.is_sensitive).unwrap_or(false),
"risk_reason": risk_analysis.and_then(|r| r.reason),
"modified_unix": modified,
"dry_run": args.dry_run,
});
println!("{line}");
}
let _ = targets;
Ok(())
}