use crate::declarations::Declaration;
use crate::runner::{MARKER, REFUSED};
use crate::trailer::counts_shape;
const TEMPLATE: &str = include_str!("prompt.md");
const TEMPLATE_SIMPLE: &str = include_str!("prompt-simple.md");
const PLACEHOLDER: &str = "<the aim of the change, stated flatly, as a spec would state it>";
fn built_in(text: &str) -> String {
text.lines().skip(1).collect::<Vec<_>>().join("\n")
}
fn asked_of(simple: bool) -> String {
format!(
"reviewer=<who reviewed> session=<this review's id> {}",
counts_shape(simple)
)
}
fn verdict_spec(declaration: &Declaration, files: &[String]) -> String {
let shape = asked_of(declaration.brief.simple);
let refusal = format!(
"\n\nIf you are refusing the brief, close with this instead, and review nothing:\n\n {MARKER} {REFUSED}"
);
let listed = files
.iter()
.map(|f| format!(" {f}"))
.collect::<Vec<_>>()
.join("\n");
format!(
"The files under review, and no others:\n{listed}\n\nClose with exactly this line, and nothing after it:\n\n {MARKER} {shape}{refusal}"
)
}
pub fn compose(
declaration: &Declaration,
intent: Option<&str>,
files: &[String],
) -> Result<String, String> {
let template = match &declaration.brief.prompt {
Some(path) => {
std::fs::read_to_string(path).map_err(|e| format!("--override-prompt {path}: {e}"))?
}
None if declaration.brief.simple => built_in(TEMPLATE_SIMPLE),
None => built_in(TEMPLATE),
};
let docs = declaration
.docs
.iter()
.map(|d| format!(" {d}"))
.collect::<Vec<_>>()
.join("\n");
Ok(template
.replace("{{gate}}", &declaration.gate)
.replace("{{docs}}", &docs)
.replace("{{intent}}", intent.unwrap_or(PLACEHOLDER))
.replace("{{verdict}}", &verdict_spec(declaration, files)))
}