//! Smoke-test contract from `docs/workpad/brainstorm/fermata.md` Appendix A.4.

use dirigent_fermata::core::{Decision, Op, Policy};
use std::fs;
use tempfile::TempDir;

fn fixture() -> TempDir {
    let tmp = TempDir::new().unwrap();
    let root = tmp.path();
    fs::write(root.join(".botignore"), ".env\n.env.*\nconf/cert/**\nconf/mitmproxy/**\n").unwrap();
    fs::write(
        root.join("botignore.toml"),
        r#"
[read]
patterns = [
  "conf/localtestsettings.yaml",
  "conf/localsettings.yaml",
  "conf/default-secrets.yaml",
  ".claude/self-reflections/**",
]

[write]
patterns = [
  "conf/localtestsettings.yaml",
  "conf/localsettings.yaml",
  "conf/default-secrets.yaml",
]

[bash]
deny = ["localtestsettings.yaml", "localsettings.yaml", "default-secrets.yaml", ".env"]
ask = ["rm *", "mv *"]
allow_prefixes = ["make test"]
"#,
    )
    .unwrap();

    fs::create_dir_all(root.join("conf")).unwrap();
    fs::create_dir_all(root.join("datatap")).unwrap();
    fs::create_dir_all(root.join(".claude/self-reflections")).unwrap();
    for f in [".env", "conf/localsettings.yaml", "datatap/foo.py", ".claude/self-reflections/x.md"] {
        fs::write(root.join(f), "").unwrap();
    }
    tmp
}

#[test]
fn read_dot_env_denied() {
    let t = fixture();
    let p = Policy::load(t.path()).unwrap();
    assert!(matches!(p.check(Op::Read, &t.path().join(".env")).unwrap(), Decision::Deny(_)));
}

#[test]
fn bash_cat_dot_env_denied() {
    let t = fixture();
    let p = Policy::load(t.path()).unwrap();
    assert!(matches!(p.check_command("cat ./.env").unwrap(), Decision::Deny(_)));
}

#[test]
fn bash_rm_localsettings_denied() {
    let t = fixture();
    let p = Policy::load(t.path()).unwrap();
    assert!(matches!(
        p.check_command("rm ./conf/localsettings.yaml").unwrap(),
        Decision::Deny(_)
    ));
}

#[test]
fn write_localsettings_denied() {
    let t = fixture();
    let p = Policy::load(t.path()).unwrap();
    assert!(matches!(
        p.check(Op::Write, &t.path().join("conf/localsettings.yaml")).unwrap(),
        Decision::Deny(_)
    ));
}

#[test]
fn edit_datatap_foo_py_allowed() {
    let t = fixture();
    let p = Policy::load(t.path()).unwrap();
    assert_eq!(
        p.check(Op::Write, &t.path().join("datatap/foo.py")).unwrap(),
        Decision::Allow
    );
}

#[test]
fn bash_make_test_allowed() {
    let t = fixture();
    let p = Policy::load(t.path()).unwrap();
    assert_eq!(p.check_command("make test").unwrap(), Decision::Allow);
}

#[test]
fn bash_rm_somefile_asks() {
    let t = fixture();
    let p = Policy::load(t.path()).unwrap();
    assert!(matches!(p.check_command("rm somefile").unwrap(), Decision::Ask(_)));
}

#[test]
fn read_self_reflections_asks() {
    // Note: A.4 has self-reflections under "ask" — current toml schema uses `[read].patterns`
    // for hard reads. This documents the gap; once toml has a `[read].ask`, switch to Ask.
    let t = fixture();
    let p = Policy::load(t.path()).unwrap();
    let d = p.check(Op::Read, &t.path().join(".claude/self-reflections/x.md")).unwrap();
    assert!(matches!(d, Decision::Deny(_)));
}
