use std::path::Path;
use crate::exit::{CtlError, CtlResult};
pub fn lint() -> CtlResult<()> {
let root = cellos_evidence::repo_root();
let entries = cellos_evidence::lint_catalog(&root)
.map_err(|e| CtlError::validation(format!("evidence lint: {e}")))?;
println!(
"evidence catalog OK: {} control-mapping entries lint-clean",
entries.len()
);
Ok(())
}
pub fn emit(out: &Path) -> CtlResult<()> {
let root = cellos_evidence::repo_root();
let entries = cellos_evidence::load_catalog(&root)
.map_err(|e| CtlError::validation(format!("evidence emit: load catalog: {e}")))?;
let pkg = cellos_evidence::emit_oscal(&entries);
std::fs::create_dir_all(out)
.map_err(|e| CtlError::usage(format!("evidence emit: mkdir {}: {e}", out.display())))?;
let cd = serde_json::to_string_pretty(&pkg.component_definition).map_err(|e| {
CtlError::validation(format!("evidence emit: serialize component-def: {e}"))
})?;
let ssp = serde_json::to_string_pretty(&pkg.ssp_fragment)
.map_err(|e| CtlError::validation(format!("evidence emit: serialize ssp: {e}")))?;
let cd_path = out.join("component-definition.json");
let ssp_path = out.join("ssp-fragment.json");
std::fs::write(&cd_path, cd)
.map_err(|e| CtlError::usage(format!("evidence emit: write {}: {e}", cd_path.display())))?;
std::fs::write(&ssp_path, ssp).map_err(|e| {
CtlError::usage(format!("evidence emit: write {}: {e}", ssp_path.display()))
})?;
println!(
"emitted OSCAL component-definition + SSP-fragment ({} controls, CANDIDATE evidence) to {}",
entries.len(),
out.display()
);
Ok(())
}