use std::{fmt, path::PathBuf};
use anyhow::{Result, bail};
use clap::Parser;
use log::info;
use pimalaya_cli::{printer::Printer, spinner::Spinner};
use pimalaya_config::toml::TomlConfig;
use schemars::JsonSchema;
use serde::Serialize;
use crate::{account::Account, client, config::Config};
#[derive(Debug, Parser)]
pub struct CheckCommand {}
impl CheckCommand {
pub fn execute(
self,
printer: &mut impl Printer,
config_paths: &[PathBuf],
account_name: Option<&str>,
) -> Result<()> {
let mut config = Config::load_or_wizard(printer, config_paths)?;
let Some((name, account_config)) = config.take_account(account_name)? else {
bail!("Cannot find account");
};
account_config.validate()?;
info!("checking account {name}");
let mode = account_config.mode()?.to_string();
let account = Account::resolve(&account_config)?;
let mut sources = Vec::new();
for endpoint in account_config.endpoints()?.keys() {
sources.push(check_source(endpoint, &account)?);
}
printer.out(CheckOutput {
account: name,
mode,
sources,
})
}
}
fn check_source(label: &str, account: &Account) -> Result<SourceCheck> {
let s = Spinner::start(format!("Checking source {label}…"));
let mut client = client::open(&account.get(label)?)?;
let collections = client.list_collections(false)?.len();
s.success(format!(
"Checked source {label} ({collections} collections)"
));
Ok(SourceCheck {
source: label.to_owned(),
collections,
})
}
#[derive(Debug, Serialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
pub struct CheckOutput {
pub account: String,
pub mode: String,
pub sources: Vec<SourceCheck>,
}
impl fmt::Display for CheckOutput {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
writeln!(f, "{mode}", mode = self.mode)?;
writeln!(f)?;
for source in &self.sources {
writeln!(f, " - {source}")?;
}
writeln!(f)?;
writeln!(f, "Account {account} looks healthy", account = self.account)
}
}
#[derive(Debug, Serialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
pub struct SourceCheck {
pub source: String,
pub collections: usize,
}
impl fmt::Display for SourceCheck {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let Self {
source,
collections,
} = self;
write!(f, "{source} ({collections} collection(s))")
}
}