//! `pic init` journey — offline scaffolding, no server/DB needed (so these
//! tests are NOT gated on `DATABASE_URL` and never touch `common::fixture`).

use std::fs;

use assert_cmd::Command;
use tempfile::TempDir;

fn pic() -> Command {
    Command::cargo_bin("pic").expect("pic binary")
}

#[test]
fn init_scaffolds_a_deployable_project() {
    let dir = TempDir::new().unwrap();
    pic()
        .current_dir(dir.path())
        .args(["init", "demo-app"])
        .assert()
        .success();

    let toml = fs::read_to_string(dir.path().join("picloud.toml")).unwrap();
    assert!(toml.contains("slug = \"demo-app\""), "got:\n{toml}");
    assert!(
        toml.contains("name = \"Demo App\""),
        "name defaults to title-cased slug:\n{toml}"
    );
    assert!(
        dir.path().join("scripts/hello.rhai").exists(),
        "scaffold writes the example script"
    );
    let gitignore = fs::read_to_string(dir.path().join(".gitignore")).unwrap();
    assert!(
        gitignore.lines().any(|l| l.trim() == ".picloud/"),
        "init must gitignore .picloud/:\n{gitignore}"
    );
}

#[test]
fn init_derives_slug_from_a_not_yet_created_dir() {
    // The natural `pic init --dir new-project` flow: the target doesn't exist
    // yet, and the slug is derived from its name (not via canonicalize, which
    // would fail on a missing path).
    let parent = TempDir::new().unwrap();
    let target = parent.path().join("new-project");
    pic()
        .args(["init", "--dir"])
        .arg(&target)
        .assert()
        .success();
    let toml = fs::read_to_string(target.join("picloud.toml")).unwrap();
    assert!(
        toml.contains("slug = \"new-project\""),
        "slug should derive from the dir name:\n{toml}"
    );
}

#[test]
fn init_refuses_to_overwrite_without_force() {
    let dir = TempDir::new().unwrap();
    pic()
        .current_dir(dir.path())
        .args(["init", "demo-app"])
        .assert()
        .success();
    // A second run must refuse rather than clobber edits.
    pic()
        .current_dir(dir.path())
        .args(["init", "demo-app"])
        .assert()
        .failure();
    // `--force` overrides.
    pic()
        .current_dir(dir.path())
        .args(["init", "demo-app", "--force"])
        .assert()
        .success();
}

#[test]
fn init_appends_to_an_existing_gitignore_once() {
    let dir = TempDir::new().unwrap();
    fs::write(dir.path().join(".gitignore"), "target/\n").unwrap();
    pic()
        .current_dir(dir.path())
        .args(["init", "demo-app"])
        .assert()
        .success();
    let gitignore = fs::read_to_string(dir.path().join(".gitignore")).unwrap();
    assert!(
        gitignore.contains("target/"),
        "must preserve existing rules"
    );
    assert_eq!(
        gitignore.matches(".picloud/").count(),
        1,
        "must add the ignore exactly once:\n{gitignore}"
    );
}
