// tests/suite/test_fs.el — comprehensive tests for runtime/fs.el
//
// Covers fs_write, fs_read, fs_exists, fs_mkdir.  All file paths use /tmp so
// no special permissions are needed.  Each test uses a unique path to prevent
// interference between test cases.

// ── fs_write / fs_read roundtrip ─────────────────────────────────────────────

fn test_fs_write_read_basic(_: String) -> String {
    let path: String = "/tmp/el_suite_test_basic.txt"
    let content: String = "hello from El tests"
    fs_write(path, content)
    let read_back: String = fs_read(path)
    assert_eq(read_back, content, "read back what was written")
    return ""
}

fn test_fs_write_read_multiline(_: String) -> String {
    let path: String = "/tmp/el_suite_test_multiline.txt"
    let content: String = "line one\nline two\nline three"
    fs_write(path, content)
    let read_back: String = fs_read(path)
    assert_eq(read_back, content, "multiline content preserved")
    assert_contains(read_back, "line one", "first line present")
    assert_contains(read_back, "line two", "second line present")
    assert_contains(read_back, "line three", "third line present")
    return ""
}

fn test_fs_write_read_empty(_: String) -> String {
    let path: String = "/tmp/el_suite_test_empty.txt"
    fs_write(path, "")
    let read_back: String = fs_read(path)
    // empty file may return "" or a zero-length string
    assert_int_eq(str_len(read_back), 0, "empty file reads as empty string")
    return ""
}

fn test_fs_write_overwrite(_: String) -> String {
    let path: String = "/tmp/el_suite_test_overwrite.txt"
    fs_write(path, "first version")
    let r1: String = fs_read(path)
    assert_eq(r1, "first version", "first write readable")

    fs_write(path, "second version")
    let r2: String = fs_read(path)
    assert_eq(r2, "second version", "second write overwrites first")

    fs_write(path, "third version")
    let r3: String = fs_read(path)
    assert_eq(r3, "third version", "third write overwrites second")
    return ""
}

fn test_fs_write_large_content(_: String) -> String {
    let path: String = "/tmp/el_suite_test_large.txt"
    let big: String = str_repeat("abcdefghij", 100)
    fs_write(path, big)
    let read_back: String = fs_read(path)
    assert_int_eq(str_len(read_back), 1000, "large content length preserved")
    assert_eq(str_slice(read_back, 0, 10), "abcdefghij", "content starts correctly")
    assert_eq(str_slice(read_back, 990, 1000), "abcdefghij", "content ends correctly")
    return ""
}

// ── fs_exists ─────────────────────────────────────────────────────────────────

fn test_fs_exists_basic(_: String) -> String {
    let path: String = "/tmp/el_suite_test_exists.txt"
    fs_write(path, "existence test")
    assert_true(fs_exists(path), "file exists after write")
    return ""
}

fn test_fs_exists_nonexistent(_: String) -> String {
    assert_false(fs_exists("/tmp/el_suite_this_file_does_not_exist_xyz_abc_999.txt"), "nonexistent file returns false")
    assert_false(fs_exists("/tmp/el_suite_another_missing_file_def.txt"), "another nonexistent file returns false")
    return ""
}

fn test_fs_write_creates_file(_: String) -> String {
    let path: String = "/tmp/el_suite_test_create.txt"
    // May or may not exist — write creates it
    fs_write(path, "newly created")
    assert_true(fs_exists(path), "file exists after creation via write")
    let content: String = fs_read(path)
    assert_eq(content, "newly created", "content correct after creation")
    return ""
}

// ── fs_read nonexistent ───────────────────────────────────────────────────────

fn test_fs_read_nonexistent(_: String) -> String {
    let result: String = fs_read("/tmp/el_suite_this_absolutely_does_not_exist_xyz.txt")
    // Per the spec: returns "" or error string; we just verify it doesn't crash
    // and returns a string (which it must, given the type system)
    assert_true(str_len(result) >= 0, "reading nonexistent file returns a string")
    return ""
}

// ── JSON content stored in files ─────────────────────────────────────────────

fn test_fs_write_json(_: String) -> String {
    let path: String = "/tmp/el_suite_test_json.txt"
    let json_data: String = "{\"name\":\"alice\",\"score\":42}"
    fs_write(path, json_data)
    let read_back: String = fs_read(path)
    assert_eq(json_get(read_back, "name"), "alice", "JSON name field after file roundtrip")
    assert_eq(json_get(read_back, "score"), "42", "JSON score field after file roundtrip")
    return ""
}

fn test_fs_write_json_array(_: String) -> String {
    let path: String = "/tmp/el_suite_test_json_arr.txt"
    let arr_data: String = "[\"alpha\",\"beta\",\"gamma\"]"
    fs_write(path, arr_data)
    let read_back: String = fs_read(path)
    assert_int_eq(json_array_len(read_back), 3, "JSON array length after file roundtrip")
    assert_eq(json_array_get_string(read_back, 0), "alpha", "first element after roundtrip")
    assert_eq(json_array_get_string(read_back, 2), "gamma", "last element after roundtrip")
    return ""
}

// ── multiple independent files ────────────────────────────────────────────────

fn test_fs_multiple_files(_: String) -> String {
    let path_a: String = "/tmp/el_suite_multi_a.txt"
    let path_b: String = "/tmp/el_suite_multi_b.txt"
    let path_c: String = "/tmp/el_suite_multi_c.txt"

    fs_write(path_a, "content A")
    fs_write(path_b, "content B")
    fs_write(path_c, "content C")

    assert_eq(fs_read(path_a), "content A", "file A reads correctly")
    assert_eq(fs_read(path_b), "content B", "file B reads correctly")
    assert_eq(fs_read(path_c), "content C", "file C reads correctly")

    assert_true(fs_exists(path_a), "file A exists")
    assert_true(fs_exists(path_b), "file B exists")
    assert_true(fs_exists(path_c), "file C exists")
    return ""
}

// ── fs_mkdir ──────────────────────────────────────────────────────────────────

fn test_fs_mkdir_basic(_: String) -> String {
    let dir_path: String = "/tmp/el_suite_mkdir_test"
    let result: Bool = fs_mkdir(dir_path)
    // fs_mkdir returns Bool; the dir should now exist
    assert_true(fs_exists(dir_path), "directory exists after mkdir")
    return ""
}

fn test_fs_mkdir_write_inside(_: String) -> String {
    let dir_path: String = "/tmp/el_suite_mkdir_subdir"
    fs_mkdir(dir_path)
    let file_path: String = dir_path + "/test_file.txt"
    fs_write(file_path, "inside directory")
    assert_true(fs_exists(file_path), "file inside mkdir'd directory exists")
    assert_eq(fs_read(file_path), "inside directory", "file inside directory readable")
    return ""
}

// ── special characters in content ────────────────────────────────────────────

fn test_fs_special_chars(_: String) -> String {
    let path: String = "/tmp/el_suite_test_special.txt"
    let content: String = "tab:\there\nnewline above\r\nwindows newline"
    fs_write(path, content)
    let read_back: String = fs_read(path)
    assert_eq(read_back, content, "special chars preserved in file")
    assert_contains(read_back, "\t", "tab preserved")
    assert_contains(read_back, "\n", "newline preserved")
    return ""
}

fn test_fs_unicode_content(_: String) -> String {
    let path: String = "/tmp/el_suite_test_unicode.txt"
    // Use ASCII art instead of actual unicode for max compatibility
    let content: String = "hello-world-test"
    fs_write(path, content)
    let read_back: String = fs_read(path)
    assert_eq(read_back, content, "content preserved")
    assert_int_eq(str_len(read_back), str_len(content), "length preserved")
    return ""
}
