use std::path::Path;
use anyhow::Result;
use crate::db::{CapturePolicy, CaptureSettings};
use crate::cli::display::format_duration_compact;
use crate::cli::output::{SettingsIgnoreListOutput, SettingsView};
use crate::cli::presentation::{emit_settings_ignore_list_output, emit_settings_view_output};
use crate::cli::schema::{
SettingsApiKeyFilterArgs, SettingsArgs, SettingsCommand, SettingsIgnoreArgs,
SettingsIgnoreBundleArgs, SettingsIgnoreCommand, SettingsIgnoreListArgs, SettingsOcrArgs,
SettingsPauseArgs, SettingsResetArgs, SettingsRetentionArgs, SettingsShowArgs,
};
use super::mutation_support::require_text_or_json;
use super::notify::notify_app_refresh;
use super::runtime::open_or_init_db;
pub(in crate::cli) fn settings(db_path: &Path, args: &SettingsArgs) -> Result<()> {
match &args.command {
SettingsCommand::Show(args) => settings_show(db_path, args),
SettingsCommand::Pause(args) => settings_pause(db_path, args),
SettingsCommand::ApiKeyFilter(args) => settings_api_key_filter(db_path, args),
SettingsCommand::Ocr(args) => settings_ocr(db_path, args),
SettingsCommand::Retention(args) => settings_retention(db_path, args),
SettingsCommand::Reset(args) => settings_reset(db_path, args),
SettingsCommand::Ignore(args) => settings_ignore(db_path, args),
}
}
fn settings_show(db_path: &Path, args: &SettingsShowArgs) -> Result<()> {
let format = require_text_or_json(args.output.resolved()?, "settings show")?;
let db = open_or_init_db(db_path)?;
let view = settings_view(db.capture_policy()?);
emit_settings_view_output(format, &view)
}
fn settings_pause(db_path: &Path, args: &SettingsPauseArgs) -> Result<()> {
let format = require_text_or_json(args.output.resolved()?, "settings pause")?;
let mut db = open_or_init_db(db_path)?;
let settings = db.set_paused(args.state.is_on())?;
notify_app_refresh();
let view = settings_view(CapturePolicy::new(settings, db.list_ignored_bundle_ids()?));
emit_settings_view_output(format, &view)
}
fn settings_api_key_filter(db_path: &Path, args: &SettingsApiKeyFilterArgs) -> Result<()> {
let format = require_text_or_json(args.output.resolved()?, "settings api-key-filter")?;
let mut db = open_or_init_db(db_path)?;
let settings = db.set_api_key_filter_enabled(args.state.is_on())?;
notify_app_refresh();
let view = settings_view(CapturePolicy::new(settings, db.list_ignored_bundle_ids()?));
emit_settings_view_output(format, &view)
}
fn settings_ocr(db_path: &Path, args: &SettingsOcrArgs) -> Result<()> {
let format = require_text_or_json(args.output.resolved()?, "settings ocr")?;
let mut db = open_or_init_db(db_path)?;
let settings = db.set_ocr_enabled(args.state.is_on())?;
notify_app_refresh();
let view = settings_view(CapturePolicy::new(settings, db.list_ignored_bundle_ids()?));
emit_settings_view_output(format, &view)
}
fn settings_retention(db_path: &Path, args: &SettingsRetentionArgs) -> Result<()> {
let format = require_text_or_json(args.output.resolved()?, "settings retention")?;
let mut db = open_or_init_db(db_path)?;
let settings = db.set_retention_seconds(args.value.retention_seconds())?;
notify_app_refresh();
let view = settings_view(CapturePolicy::new(settings, db.list_ignored_bundle_ids()?));
emit_settings_view_output(format, &view)
}
fn settings_reset(db_path: &Path, args: &SettingsResetArgs) -> Result<()> {
let format = require_text_or_json(args.output.resolved()?, "settings reset")?;
let mut db = open_or_init_db(db_path)?;
let view = settings_view(db.reset_capture_policy()?);
notify_app_refresh();
emit_settings_view_output(format, &view)
}
fn settings_ignore(db_path: &Path, args: &SettingsIgnoreArgs) -> Result<()> {
match &args.command {
SettingsIgnoreCommand::Add(args) => settings_ignore_add(db_path, args),
SettingsIgnoreCommand::Remove(args) => settings_ignore_remove(db_path, args),
SettingsIgnoreCommand::List(args) => settings_ignore_list(db_path, args),
}
}
fn settings_ignore_add(db_path: &Path, args: &SettingsIgnoreBundleArgs) -> Result<()> {
let format = require_text_or_json(args.output.resolved()?, "settings ignore add")?;
let mut db = open_or_init_db(db_path)?;
db.add_ignored_bundle_id(&args.bundle_id)?;
notify_app_refresh();
let output = SettingsIgnoreListOutput {
ignored_bundle_ids: db.list_ignored_bundle_ids()?,
};
emit_settings_ignore_list_output(format, &output)
}
fn settings_ignore_remove(db_path: &Path, args: &SettingsIgnoreBundleArgs) -> Result<()> {
let format = require_text_or_json(args.output.resolved()?, "settings ignore remove")?;
let mut db = open_or_init_db(db_path)?;
db.remove_ignored_bundle_id(&args.bundle_id)?;
notify_app_refresh();
let output = SettingsIgnoreListOutput {
ignored_bundle_ids: db.list_ignored_bundle_ids()?,
};
emit_settings_ignore_list_output(format, &output)
}
fn settings_ignore_list(db_path: &Path, args: &SettingsIgnoreListArgs) -> Result<()> {
let format = require_text_or_json(args.output.resolved()?, "settings ignore list")?;
let db = open_or_init_db(db_path)?;
let output = SettingsIgnoreListOutput {
ignored_bundle_ids: db.list_ignored_bundle_ids()?,
};
emit_settings_ignore_list_output(format, &output)
}
fn settings_view(policy: CapturePolicy) -> SettingsView {
SettingsView {
paused: policy.settings().paused(),
api_key_filter_enabled: policy.settings().api_key_filter_enabled(),
ocr_enabled: policy.settings().ocr_enabled(),
retention_seconds: policy.settings().retention_seconds(),
retention: render_retention_value(policy.settings()),
ignored_bundle_ids: policy.ignored_bundle_ids().to_vec(),
}
}
fn render_retention_value(settings: &CaptureSettings) -> String {
settings
.retention_seconds()
.map(format_duration_compact)
.unwrap_or_else(|| "forever".to_string())
}