///|
/// —— 外部判据闸门([gate:required],默认关闭即现状)——
///
/// 背景:LLM 执行方与 LLM 测试方同源,"cargo test 全绿"不构成验收判据
/// (自写自测恒绿)。本闸门是流水线中第一个**非 LLM 判据源**的强制关口:
///   1) 任务 description 含 [gate:required] 时,verify 之前必须先由
///      服务端 run_check 工具**真实执行**一条外部命令(如 bash
///      scripts/e2e_golden.sh:真跑可执行产物 + golden diff)并把结果
///      落库(specs 表,spec_type="check",status="passed"/"failed");
///   2) 闸门校验该记录**新鲜**——检查时间必须不早于任务最后一次
///      updated_at(防止改完代码后用旧的一次通过记录蒙混);
///   3) 未标记任务行为与现状完全一致(零侵入)。
///
/// 记录 content 为 run_check 产出的 JSON 文本(exit/stdout/stderr),
/// 人类可直接在库内复核真实命令输出。

///|
/// 外部判据标记:出现在任务 description 中即表示该任务验收必须过闸门。
pub fn gate_mark() -> String {
  "[gate:required]"
}

///|
/// 任务是否开启外部判据闸门。
pub fn gate_enabled(t : @core.Task) -> Bool {
  t.get_description().contains(gate_mark())
}

///|
/// 从 run_check 的检查结果 JSON 推导权威门禁状态:`ok == true`(即 exit_code==0)
/// 记为 "passed",其余一律 "failed"(fail-closed)。不信任调用方传入的 status 字符串,
/// 防止伪造 "passed" 蒙混过关(与 gate_verify_gate 的判据一致)。
fn _derived_check_status(check_json : String) -> String {
  let parsed = @json.parse(check_json) catch { _ => return "failed" }
  match parsed {
    Object(m) =>
      match m.get("ok") {
        Some(True) => "passed"
        _ => "failed"
      }
    _ => "failed"
  }
}

///|
/// 从 run_check 的结果 JSON 里取某个文本字段的**末 n 个字符**(BUG-75)。
/// 判据红了只给退出码等于没给证据:调用方要么本地重跑一遍同一条命令(那就退回到
/// "自写自测"这条 run_check 正是要防的路径),要么整单打回却不知打回原因。
/// 解析失败 / 字段缺失 / 字段不是字符串一律回 ("", false)——记录已落库,
/// 取不到尾巴不该让回执本身失败。
fn _json_str_tail(check_json : String, key : String, n : Int) -> (String, Bool) {
  let parsed = @json.parse(check_json) catch { _ => return ("", false) }
  match parsed {
    Object(m) =>
      match m.get(key) {
        Some(String(s)) => {
          let cs = s.to_array()
          let len = cs.length()
          if len <= n {
            (s, false)
          } else {
            let out : Array[Char] = []
            let mut i = len - n
            while i < len {
              out.push(cs[i])
              i = i + 1
            }
            (String::from_array(out), true)
          }
        }
        _ => ("", false)
      }
    _ => ("", false)
  }
}

///|
/// 回执携带的输出尾巴上限(字符)。取"末 N"而不是"前 N":判据的关键信息在结尾
/// (失败断言、汇总行、exit code 说明),前 N 往往是命令回显或进度条。
fn gate_check_tail_limit() -> Int {
  2000
}

///|
/// 记录一次外部命令检查结果(门禁状态从 check_json 的 ok/exit_code==0 推导,
/// status 参数已不参与判定,仅保留以维持公开签名兼容)。
/// 记录 id = check::r(round = 该任务已有 check 记录数 + 1)。
pub fn FistEngine::gate_check_record(
  self : FistEngine,
  task_id : String,
  check_json : String,
  status : String,
  now : String,
) -> Result[Json, String] {
  // status 参数不再被信任:实际门禁状态一律由 check_json 推导
  ignore(status)
  let eff = _derived_check_status(check_json)
  match self.store.get_task(task_id) {
    None => Err("task not found: \{task_id}")
    Some(_) => {
      let round = self.omega_count_type(task_id, "check") + 1
      let rec = @store.SpecRecord::new(
        id="check:\{task_id}:r\{round}",
        task_id~,
        spec_type="check",
        content=check_json,
        status=eff,
        created_at=now,
        updated_at=now,
      )
      match self.store.upsert_spec(rec) {
        Err(e) => Err(e)
        Ok(_) => {
          let m : Map[String, Json] = Map([])
          let (out_tail, out_cut) = _json_str_tail(
            check_json,
            "stdout",
            gate_check_tail_limit(),
          )
          let (err_tail, err_cut) = _json_str_tail(
            check_json,
            "stderr",
            gate_check_tail_limit(),
          )
          m.set("ok", Json::boolean(true))
          m.set("check_id", Json::string(rec.id))
          m.set("task_id", Json::string(task_id))
          m.set("round", Json::number(round.to_double()))
          // BUG-75:回显**推导后**的门禁状态,不再回显调用方传入的 status——
          // 上面第 57 行已声明该参数不被信任,回执与记录分着说两套话就是给伪证留口子。
          m.set("status", Json::string(eff))
          // BUG-75:把判据的实际输出带回去(末 N 字符),passed 也带,
          // 否则"通过性证据"举不出判据打了什么,只能本地重跑同一条命令。
          m.set("stdout_tail", Json::string(out_tail))
          m.set("stderr_tail", Json::string(err_tail))
          m.set("output_truncated", Json::boolean(out_cut || err_cut))
          m.set(
            "note",
            Json::string(
              "外部判据已落库;若任务带 [gate:required],verify 将校验本记录新鲜度(created_at >= 任务 updated_at)。stdout_tail/stderr_tail 为末 \{gate_check_tail_limit()} 字符,完整结果见 specs 表 content",
            ),
          )
          Ok(Json::object(m))
        }
      }
    }
  }
}

///|
/// 验收前闸门:[gate:required] 任务须存在**最新且通过且新鲜**的 check 记录。
/// 未标记任务直接放行(默认关闭即现状)。
pub fn FistEngine::gate_verify_gate(
  self : FistEngine,
  task_id : String,
) -> Result[Unit, String] {
  match self.store.get_task(task_id) {
    None => Ok(())
    Some(t) =>
      if !gate_enabled(t) {
        Ok(())
      } else {
        match self.omega_latest(task_id, "check") {
          None =>
            Err(
              "外部判据闸门:任务 [\{task_id}] 带 [gate:required],但尚无外部检查记录。请先由服务端执行 run_check(真实运行外部命令并落库)",
            )
          Some(c) =>
            if c.status != "passed" {
              Err(
                "外部判据闸门:任务 [\{task_id}] 最新外部检查 [\{c.id}] 状态为 [\{c.status}],未通过前禁止验收",
              )
            } else if c.created_at < t.get_updated_at() {
              Err(
                "外部判据闸门:任务 [\{task_id}] 的检查记录 [\{c.id}](\{c.created_at})早于任务最后更新(\{t.get_updated_at()}),代码可能已变更,请重新执行 run_check",
              )
            } else {
              Ok(())
            }
        }
      }
  }
}