use assert_cmd::Command;
use std::io::Read;
use tempfile::TempDir;

#[test]
fn test_session_export_creates_zip() {
    let home = TempDir::new().unwrap();

    // Set up mock Claude Code session structure
    let projects = home.path().join(".claude").join("projects");
    let proj_dir = projects.join("-mock-project");
    std::fs::create_dir_all(&proj_dir).unwrap();

    // Write a mock session .jsonl file
    let session_content = r#"{"type":"session","sessionId":"abc-123"}
{"type":"message","content":"hello"}
"#;
    std::fs::write(proj_dir.join("abc-123.jsonl"), session_content).unwrap();

    // Write project-config.json
    let cfg = home.path().join(".claude").join("project-config.json");
    let cfg_content =
        r#"{"-mock-project":{"originalPath":"/tmp/mock-project","manuallyAdded":true}}"#;
    std::fs::write(cfg, cfg_content).unwrap();

    let out = home.path().join("sessions.zip");

    let mut cmd = Command::cargo_bin("closure").unwrap();
    cmd.env("HOME", home.path());
    cmd.arg("session")
        .arg("export")
        .arg(out.to_str().unwrap());
    cmd.assert().success();

    // Read back the ZIP and verify contents
    let zip_bytes = std::fs::read(&out).unwrap();
    let reader = std::io::Cursor::new(zip_bytes);
    let mut archive = zip::ZipArchive::new(reader).unwrap();

    // Check manifest (scope the file borrow)
    let manifest_str = {
        let mut file = archive.by_name("manifest.json").unwrap();
        let mut s = String::new();
        file.read_to_string(&mut s).unwrap();
        s
    };
    let manifest: serde_json::Value = serde_json::from_str(&manifest_str).unwrap();
    assert_eq!(manifest["session_count"], 1);
    assert_eq!(manifest["source"], "closure session export");
    assert!(manifest["exported_at"].is_string());

    // Check project-config.json
    let cfg_str = {
        let mut file = archive.by_name("project-config.json").unwrap();
        let mut s = String::new();
        file.read_to_string(&mut s).unwrap();
        s
    };
    assert!(cfg_str.contains("mock-project"));

    // Check the session file itself
    let sess_str = {
        let mut file = archive.by_name("-mock-project/abc-123.jsonl").unwrap();
        let mut s = String::new();
        file.read_to_string(&mut s).unwrap();
        s
    };
    assert!(sess_str.contains("abc-123"));
}

#[test]
fn test_session_export_empty_dir_errors() {
    let home = TempDir::new().unwrap();
    let projects = home.path().join(".claude").join("projects");
    std::fs::create_dir_all(&projects).unwrap();

    let out = home.path().join("sessions.zip");

    let mut cmd = Command::cargo_bin("closure").unwrap();
    cmd.env("HOME", home.path());
    cmd.arg("session")
        .arg("export")
        .arg(out.to_str().unwrap());
    cmd.assert().failure();
}
