//! `pic pull` journey: stand up an app with a script, route, cron trigger,
//! and a secret, then export it and assert the manifest + script file.

use tempfile::TempDir;

use crate::common;

#[ignore = "needs DATABASE_URL pointing at a running Postgres"]
#[test]
fn pull_exports_manifest_and_sources() {
    let Some(fx) = common::fixture_or_skip() else {
        return;
    };
    let env = common::admin_env(fx);

    // App + script "hello" (deploy derives the name from the file stem).
    let (script_id, guard) = common::deploy_fixture(&env, "pull", "hello.rhai");
    let app = guard.slug().to_string();

    // Route → script.
    common::pic_as(&env)
        .args([
            "routes", "create", "--script", &script_id, "--path", "/hook", "--method", "POST",
        ])
        .assert()
        .success();

    // Cron trigger → script.
    common::pic_as(&env)
        .args([
            "triggers",
            "create-cron",
            "--app",
            &app,
            "--script",
            &script_id,
            "--schedule",
            "0 0 * * * *",
        ])
        .assert()
        .success();

    // Secret (name only ends up in the manifest; value stays server-side).
    common::pic_as(&env)
        .args(["secrets", "set", "--app", &app, "api_key"])
        .write_stdin("xyzzy")
        .assert()
        .success();

    // Pull into a scratch dir.
    let out_dir = TempDir::new().expect("pull tempdir");
    common::pic_as(&env)
        .args(["pull", &app, "--dir"])
        .arg(out_dir.path())
        .assert()
        .success();

    // Manifest exists and captures every resource.
    let manifest = std::fs::read_to_string(out_dir.path().join("picloud.toml"))
        .expect("picloud.toml should be written");
    assert!(
        manifest.contains(&format!("slug = \"{app}\"")),
        "manifest missing app slug:\n{manifest}"
    );
    assert!(
        manifest.contains("name = \"hello\"") && manifest.contains("scripts/hello.rhai"),
        "manifest missing script entry:\n{manifest}"
    );
    assert!(
        manifest.contains("[[routes]]") && manifest.contains("path = \"/hook\""),
        "manifest missing route:\n{manifest}"
    );
    assert!(
        manifest.contains("[[triggers.cron]]") && manifest.contains("schedule = \"0 0 * * * *\""),
        "manifest missing cron trigger:\n{manifest}"
    );
    assert!(
        manifest.contains("api_key"),
        "manifest missing secret name:\n{manifest}"
    );

    // Script source was written out faithfully.
    let src = std::fs::read_to_string(out_dir.path().join("scripts/hello.rhai"))
        .expect("scripts/hello.rhai should be written");
    assert!(
        src.contains("hello from pic"),
        "exported source mismatch:\n{src}"
    );

    drop(guard);
}
