auv-cli 0.0.24

AUV core command-line frontend
use clap::{Args, Subcommand};

#[derive(Clone, Debug, Args)]
pub struct SetupArgs {
  #[command(subcommand)]
  command: SetupCommand,
}

#[derive(Clone, Debug, Subcommand)]
enum SetupCommand {
  /// Manage the signed helper used for locked macOS sessions.
  MacosHelper(MacosHelperArgs),
}

#[derive(Clone, Debug, Args)]
struct MacosHelperArgs {
  #[command(subcommand)]
  command: MacosHelperCommand,
}

#[derive(Clone, Debug, Subcommand)]
enum MacosHelperCommand {
  /// Report the installed helper identity and current-user readiness.
  Status {
    /// Emit a stable machine-readable result.
    #[arg(long)]
    json: bool,
  },
  /// Install and register the signed helper embedded in this AUV build.
  Install {
    /// Emit a stable machine-readable result after installation.
    #[arg(long)]
    json: bool,
  },
  /// Unregister the helper, reset Accessibility, and remove its app bundle.
  Uninstall {
    /// Emit a stable machine-readable result after removal.
    #[arg(long)]
    json: bool,
  },
  /// Open System Settings at Privacy & Security > Accessibility.
  OpenAccessibilitySettings,
  /// Open System Settings at General > Login Items & Extensions.
  OpenBackgroundItemsSettings,
}

pub fn run(args: SetupArgs) -> Result<i32, String> {
  #[cfg(target_os = "macos")]
  {
    match args.command {
      SetupCommand::MacosHelper(args) => match args.command {
        MacosHelperCommand::Status { json } => {
          print_status(&auv_device_helper_macos::setup::status(), json)?;
          Ok(0)
        }
        MacosHelperCommand::Install { json } => {
          let status = auv_device_helper_macos::setup::install().map_err(|error| error.to_string())?;
          print_status(&status, json)?;
          Ok(0)
        }
        MacosHelperCommand::Uninstall { json } => {
          let status = auv_device_helper_macos::setup::uninstall().map_err(|error| error.to_string())?;
          print_status(&status, json)?;
          Ok(0)
        }
        MacosHelperCommand::OpenAccessibilitySettings => {
          auv_device_helper_macos::setup::open_accessibility_settings().map_err(|error| error.to_string())?;
          println!("opened macOS Accessibility settings for AUV Helper authorization");
          Ok(0)
        }
        MacosHelperCommand::OpenBackgroundItemsSettings => {
          auv_device_helper_macos::setup::open_background_items_settings().map_err(|error| error.to_string())?;
          println!("opened macOS Login Items settings for AUV Helper authorization");
          Ok(0)
        }
      },
    }
  }

  #[cfg(not(target_os = "macos"))]
  {
    let _ = args;
    Err("macOS helper setup is available only on macOS".to_string())
  }
}

#[cfg(target_os = "macos")]
fn print_status(status: &auv_device_helper_macos::setup::Status, json: bool) -> Result<(), String> {
  if json {
    println!(
      "{}",
      serde_json::to_string_pretty(&serde_json::json!({
        "state": status.state.as_str(),
        "detail": status.detail,
        "helper_embedded": status.helper_embedded,
      }))
      .map_err(|error| format!("failed to encode helper status: {error}"))?
    );
  } else {
    println!("state\t{}", status.state.as_str());
    println!("helper_embedded\t{}", status.helper_embedded);
    if let Some(detail) = &status.detail {
      println!("detail\t{detail}");
    }
  }

  Ok(())
}