use crate::core::shell_escape::sh_squote;
use crate::core::types::Resource;
use crate::resources::verdict;
const SUDO_PREAMBLE: &str = "SUDO=\"\"\n[ \"$(id -u)\" -ne 0 ] && SUDO=\"sudo\"";
const CRONTAB_CHECK_GUARD: &str = "\
if [ \"$(id -u)\" -ne 0 ] && ! sudo -n true >/dev/null 2>&1; then\n \
echo 'FORJAR_SKIP: sudo unavailable - crontab state is not observable here'\n \
exit 2\n\
fi";
fn delete_block(marker: &str, cmd_marker: &str) -> String {
format!(
"FJ_M={marker} FJ_C={cmd_marker} awk \
'$0==ENVIRON[\"FJ_M\"]{{d=1;next}} \
d==1&&$0==ENVIRON[\"FJ_C\"]{{d=2;next}} \
d==2{{d=0;next}} {{d=0}} 1'"
)
}
fn crontab_user(resource: &Resource) -> String {
sh_squote(resource.owner.as_deref().unwrap_or("root"))
}
pub fn check_script(resource: &Resource) -> String {
let name = resource.name.as_deref().unwrap_or("unknown");
let u = crontab_user(resource);
let marker = sh_squote(&format!("# forjar:{name}"));
let verdict = verdict::single(
&format!("$SUDO crontab -u {u} -l 2>/dev/null | grep -qFx {marker}"),
&format!("exists:{name}"),
&format!("missing:{name}"),
);
format!("{CRONTAB_CHECK_GUARD}\n{SUDO_PREAMBLE}\n{verdict}")
}
pub fn apply_script(resource: &Resource) -> String {
let name = resource.name.as_deref().unwrap_or("unknown");
let state = resource.state.as_deref().unwrap_or("present");
let u = crontab_user(resource);
let marker = sh_squote(&format!("# forjar:{name}"));
let cmd_marker = sh_squote(&format!("# forjar-cmd:{name}"));
let strip = delete_block(&marker, &cmd_marker);
match state {
"absent" => format!(
"set -euo pipefail\n\
{SUDO_PREAMBLE}\n\
EXISTING=$($SUDO crontab -u {u} -l 2>/dev/null || true)\n\
echo \"$EXISTING\" | {strip} | $SUDO crontab -u {u} -"
),
_ => {
let schedule = resource.schedule.as_deref().unwrap_or("* * * * *");
let command = resource.command.as_deref().unwrap_or("true");
let entry = sh_squote(&format!("{schedule} {command}"));
format!(
"set -euo pipefail\n\
{SUDO_PREAMBLE}\n\
EXISTING=$($SUDO crontab -u {u} -l 2>/dev/null | {strip} || true)\n\
{{\n\
echo \"$EXISTING\"\n\
echo {marker}\n\
echo {cmd_marker} \n\
echo {entry}\n\
}} | $SUDO crontab -u {u} -"
)
}
}
}
pub fn state_query_script(resource: &Resource) -> String {
let name = resource.name.as_deref().unwrap_or("unknown");
let u = crontab_user(resource);
let marker = sh_squote(&format!("# forjar:{name}"));
format!(
"{SUDO_PREAMBLE}\n\
$SUDO crontab -u {u} -l 2>/dev/null | grep -A2 -Fx {marker} || echo {}",
sh_squote(&format!("cron=MISSING:{name}"))
)
}