use std::io::{IsTerminal, Write};
use tape::{encode_nested, kv, render, sigil, Chunk, Writer};
use crate::style::{self, paint};
pub type Row = (&'static str, String);
fn tty() -> bool {
std::io::stdout().is_terminal()
}
fn color() -> bool {
tty() && std::env::var_os("NO_COLOR").is_none()
}
pub fn report(title: &str, rows: &[Row]) {
if tty() {
print_report(title, rows, color());
} else {
let pairs: Vec<Chunk> = rows.iter().map(|(k, v)| kv(k, Chunk::text(v))).collect();
write_tape(&Chunk::new(sigil::BAR, render::STRUCT, encode_nested(&pairs)));
}
}
fn print_report(title: &str, rows: &[Row], color: bool) {
let width = rows.iter().map(|(k, _)| k.len()).max().unwrap_or(0);
println!();
println!(" {} {}", paint(color, style::C, "่จผ"), paint(color, style::W, title));
for (k, v) in rows {
let key = paint(color, style::GR, &format!("{k:<width$}"));
let val = match *k {
"verify" => {
let col = if v == "ok" { style::G } else { style::R };
paint(color, col, v)
}
k if k.ends_with("_ms") => paint(color, style::DIM, v),
_ => paint(color, style::W, v),
};
println!(" {key} {val}");
}
println!();
}
pub fn error(message: &str) {
if tty() {
println!(" {} {}", paint(color(), style::R, "โ"), paint(color(), style::R, message));
} else {
write_tape(&Chunk::error(message));
}
}
pub fn status(code: i32) {
if !tty() {
write_tape(&Chunk::status(code));
}
}
fn write_tape(chunk: &Chunk) {
let stdout = std::io::stdout();
let mut writer = Writer::new(stdout.lock());
let _ = writer.write_chunk(chunk);
let _ = writer.into_inner().flush();
}