use std::io::{self, IsTerminal, Write};
use std::time::Duration;
use anyhow::Result;
use aranet_core::{BluetoothRange, MeasurementInterval};
use crate::cli::{BluetoothRangeSetting, DeviceSetting};
use crate::util::{connect_device_with_progress, require_device_interactive};
fn confirm_change(message: &str, force: bool) -> Result<bool> {
if force {
return Ok(true);
}
if !io::stdin().is_terminal() {
eprintln!("Error: Cannot prompt for confirmation in non-interactive mode.");
eprintln!("Use --force to skip confirmation.");
return Ok(false);
}
print!("{} [y/N]: ", message);
io::stdout().flush()?;
let mut input = String::new();
io::stdin().read_line(&mut input)?;
let response = input.trim().to_lowercase();
Ok(response == "y" || response == "yes")
}
fn describe_setting_change(setting: &DeviceSetting) -> String {
match setting {
DeviceSetting::Interval { minutes } => {
format!("Change measurement interval to {} minute(s)?", minutes)
}
DeviceSetting::Range { range } => {
let range_str = match range {
BluetoothRangeSetting::Standard => "Standard",
BluetoothRangeSetting::Extended => "Extended",
};
format!("Change Bluetooth range to {}?", range_str)
}
DeviceSetting::SmartHome { enabled } => {
if *enabled {
"Enable Smart Home integration?".to_string()
} else {
"Disable Smart Home integration?".to_string()
}
}
}
}
pub async fn cmd_set(
device: Option<String>,
timeout: Duration,
setting: DeviceSetting,
quiet: bool,
force: bool,
) -> Result<()> {
let identifier = require_device_interactive(device).await?;
let confirmation_msg = describe_setting_change(&setting);
if !confirm_change(&confirmation_msg, force)? {
eprintln!("Cancelled.");
return Ok(());
}
let device = connect_device_with_progress(&identifier, timeout, !quiet).await?;
let update_result = match setting {
DeviceSetting::Interval { minutes } => {
let interval = MeasurementInterval::from_minutes(minutes).ok_or_else(|| {
anyhow::anyhow!(
"Invalid interval: {}. Valid values: 1, 2, 5, 10 minutes.",
minutes
)
})?;
device.set_interval(interval).await?;
if !quiet {
println!("Measurement interval set to {} minute(s)", minutes);
}
Ok(())
}
DeviceSetting::Range { range } => {
let bt_range = match range {
BluetoothRangeSetting::Standard => BluetoothRange::Standard,
BluetoothRangeSetting::Extended => BluetoothRange::Extended,
};
device.set_bluetooth_range(bt_range).await?;
if !quiet {
println!("Bluetooth range set to {:?}", bt_range);
}
Ok(())
}
DeviceSetting::SmartHome { enabled } => {
device.set_smart_home(enabled).await?;
if !quiet {
println!(
"Smart Home integration {}",
if enabled { "enabled" } else { "disabled" }
);
}
Ok(())
}
};
crate::util::disconnect_device(&device).await;
update_result
}