use std::io::Write;
use std::path::PathBuf;
const TEE_DIR: &str = "/tmp/reliary-tee";
pub fn save_tee(raw: &str) -> std::io::Result<Option<String>> {
if raw.is_empty() { return Ok(None); }
if std::env::var("RELIARY_NO_TEE").is_ok_and(|v| v == "1") { return Ok(None); }
let hash = sha256_hex(raw);
let dir = PathBuf::from(TEE_DIR);
std::fs::create_dir_all(&dir)?;
let path = dir.join(&hash);
let tmp_path = dir.join(format!(".{}.tmp", hash));
{
let mut f = std::fs::File::create(&tmp_path)?;
f.write_all(raw.as_bytes())?;
f.sync_all()?;
}
std::fs::rename(&tmp_path, &path)?;
Ok(Some(path.to_string_lossy().into_owned()))
}
#[allow(dead_code)]
pub fn read_tee(hash_or_path: &str) -> std::io::Result<String> {
let path = if hash_or_path.contains('/') || hash_or_path.ends_with(".log") {
PathBuf::from(hash_or_path)
} else {
PathBuf::from(TEE_DIR).join(hash_or_path)
};
std::fs::read_to_string(&path)
}
#[allow(dead_code)]
pub fn list_tee_files() -> std::io::Result<Vec<(String, u64)>> {
let dir = PathBuf::from(TEE_DIR);
if !dir.exists() { return Ok(Vec::new()); }
let mut out = Vec::new();
for entry in std::fs::read_dir(&dir)? {
let entry = entry?;
let name = entry.file_name().to_string_lossy().to_string();
if name.starts_with('.') { continue; } let size = entry.metadata().map(|m| m.len()).unwrap_or(0);
out.push((name, size));
}
out.sort();
Ok(out)
}
pub fn clean_tee() -> std::io::Result<u64> {
let dir = PathBuf::from(TEE_DIR);
if !dir.exists() { return Ok(0); }
let mut removed = 0u64;
for entry in std::fs::read_dir(&dir)? {
let entry = entry?;
let name = entry.file_name().to_string_lossy().to_string();
if name.starts_with('.') { continue; }
let size = entry.metadata().map(|m| m.len()).unwrap_or(0);
if std::fs::remove_file(entry.path()).is_ok() { removed += size; }
}
Ok(removed)
}
fn sha256_hex(input: &str) -> String {
use std::hash::{Hash, Hasher};
let mut h = std::collections::hash_map::DefaultHasher::new();
input.hash(&mut h);
format!("{:016x}", h.finish())
}