//! `cellctl get formations` / `cellctl get cells` — list resources.
//!
//! Each subcommand corresponds to **exactly one** HTTP GET (Feynman's rule from
//! CHATROOM Session 16). Filters that the server understands (`?formation=`) are
//! forwarded as query params; nothing is filtered client-side.

use crate::client::CellosClient;
use crate::exit::CtlResult;
use crate::model::{CellsSnapshot, FormationsSnapshot};
use crate::output::{self, OutputFormat};

pub async fn formations(client: &CellosClient, fmt: OutputFormat) -> CtlResult<()> {
    // MED-CTL-001-A: typed snapshot per endpoint; previously this used a
    // generic `List<T>` whose `formations`/`cells`/`items` alias collapse
    // could silently drop half a mixed envelope.
    let snap: FormationsSnapshot = client.get_json("/v1/formations").await?;
    output::render_formations(&snap.formations, fmt);
    Ok(())
}

pub async fn cells(
    client: &CellosClient,
    formation: Option<&str>,
    fmt: OutputFormat,
) -> CtlResult<()> {
    let path = match formation {
        Some(f) => format!("/v1/cells?formation={}", urlencode(f)),
        None => "/v1/cells".to_string(),
    };
    let snap: CellsSnapshot = client.get_json(&path).await?;
    output::render_cells(&snap.cells, fmt);
    Ok(())
}

fn urlencode(s: &str) -> String {
    percent_encoding::utf8_percent_encode(s, percent_encoding::NON_ALPHANUMERIC).collect()
}
