// el-platform — Platform abstraction surface for el-ui apps.
//
// The Rust crate defines `PlatformBackend` trait + per-target render backends
// (web/server/ios/android/macos/linux/windows). The El surface is narrower:
// El apps reach the host through the runtime's filesystem, network, and OS
// primitives. This vessel wraps those into a stable, named API so El callers
// don't depend directly on builtin names.
//
// RUNTIME PARITY GAPS:
//   - There is no `PlatformBackend` polymorphism at the El layer. The runtime
//     IS the backend; target selection happens during compilation/packaging,
//     not at runtime.
//   - DOM mutation, native widget mounting, event binding — none of those
//     have El surfaces yet. Use el-ui-compiler when those land.
//   - `fs_list` returns a JSON array string; consumers must parse with the
//     forthcoming json_array_get builtin. Until that lands, callers should
//     treat the value opaquely.

// ── Targets ─────────────────────────────────────────────────────────────────

fn target_web()     -> String { "web" }
fn target_server()  -> String { "server" }
fn target_ios()     -> String { "ios" }
fn target_android() -> String { "android" }
fn target_macos()   -> String { "macos" }
fn target_linux()   -> String { "linux" }
fn target_windows() -> String { "windows" }

// The compiled binary's target is fixed at build time. EL_TARGET is set by
// the build harness; absent EL_TARGET, default to "server" (the El runtime
// runs as a host process).
fn platform_target() -> String {
    let t: String = env("EL_TARGET")
    if str_eq(t, "") { return "server" }
    t
}

fn platform_is_native(t: String) -> Bool {
    if str_eq(t, "ios")     { return true }
    if str_eq(t, "android") { return true }
    if str_eq(t, "macos")   { return true }
    if str_eq(t, "linux")   { return true }
    if str_eq(t, "windows") { return true }
    false
}

fn platform_supports_ssr(t: String) -> Bool {
    str_eq(t, "server")
}

// ── Errors ──────────────────────────────────────────────────────────────────

fn err_io()          -> String { "platform.io" }
fn err_network()     -> String { "platform.network" }
fn err_unsupported() -> String { "platform.unsupported" }
fn err_env_missing() -> String { "platform.env_missing" }

// ── Environment ─────────────────────────────────────────────────────────────

fn platform_env(key: String) -> String {
    env(key)
}

fn platform_env_or(key: String, fallback: String) -> String {
    let v: String = env(key)
    if str_eq(v, "") { return fallback }
    v
}

// Strict variant: returns "" if missing, callers branch.
// (Runtime has no panic() — fail-soft return preserves type.)
fn platform_env_required(key: String) -> String {
    let v: String = env(key)
    if str_eq(v, "") {
        println("[el-platform] ERROR " + err_env_missing() + ":" + key)
        return ""
    }
    v
}

// ── Filesystem ──────────────────────────────────────────────────────────────

fn platform_fs_read(path: String) -> String {
    fs_read(path)
}

fn platform_fs_write(path: String, content: String) -> Bool {
    fs_write(path, content)
    true
}

// Returns a JSON array of entry names (opaque until json_array_get lands).
fn platform_fs_list(path: String) -> String {
    let raw: String = fs_list(path)
    if str_eq(raw, "") { return "[]" }
    raw
}

fn platform_fs_exists(path: String) -> Bool {
    let raw: String = fs_read(path)
    !str_eq(raw, "")
}

// ── HTTP ────────────────────────────────────────────────────────────────────

fn platform_http_get(url: String) -> String {
    http_get(url)
}

fn platform_http_post(url: String, body: String) -> String {
    http_post(url, body)
}

fn platform_http_post_json(url: String, json_body: String) -> String {
    http_post_json(url, json_body)
}

fn platform_http_get_authed(url: String, bearer: String) -> String {
    let headers: String = "Authorization: Bearer " + bearer
    http_get_with_headers(url, headers)
}

fn platform_http_post_authed(url: String, body: String, bearer: String) -> String {
    let headers: String = "Authorization: Bearer " + bearer
    http_post_with_headers(url, body, headers)
}

// ── Time / OS clock ─────────────────────────────────────────────────────────

fn platform_now() -> Int {
    time_now()
}

fn platform_sleep_ms(ms: Int) -> Bool {
    sleep_ms(ms)
    true
}

// ── Identity (for trace/log correlation) ───────────────────────────────────

fn platform_uuid() -> String {
    uuid_v4()
}

// ── Entry — smoke test ──────────────────────────────────────────────────────
//
// elc-bug-workaround: top-level `let` does not scope into the surrounding
// statement substitution in the entry block, so we call platform_target()
// inline at each use site.

println("[el-platform] target=" + platform_target() + " ssr=" + bool_to_str(platform_supports_ssr(platform_target())))
println("[el-platform] uuid=" + platform_uuid())
