//! # islands — umbrella crate for islands.rs
//!
//! This is the single dependency users should add to consume the islands.rs framework.
//! All public APIs from the underlying sub-crates are re-exported here so a downstream
//! `Cargo.toml` looks like:
//!
//! ```toml
//! [dependencies]
//! islands = { path = "...", features = ["basecoat"] }   # basecoat optional
//! ```
//!
//! and a downstream `main.rs` looks like:
//!
//! ```rust,ignore
//! use islands::prelude::*;
//! ```
//!
//! ## What's in the box
//!
//! The framework is a Rust SSR + island-hydration system with shared-core WASM code
//! splitting. The server emits plain HTML with labelled island markers; each island is
//! mounted independently on the client. No whole-page hydration, no virtual-DOM
//! reconciliation, no hydration-mismatch failure mode. See [`plan.md`] for the full
//! architectural rationale.
//!
//! Modules at a glance:
//!
//! | Re-export | What it provides |
//! |---|---|
//! | [`island_marker`], [`page_shell`], [`page_shell_streaming_head`] | Server-side HTML markup helpers that emit island placeholders, the document shell, and the streaming-shell head fragment. |
//! | [`Suspense`], [`render_streaming`], [`render_streaming_with`], [`HtmlChunk`], [`StreamError`], [`REPLACE_SCRIPT`] | Streaming SSR with Suspense boundaries — out-of-order chunk delivery, `<template>` + `$ISLANDS_REPLACE` script-based slot filling. |
//! | [`Manifest`], [`ManifestEntry`] | Content-hashed asset manifest loaded at startup; `page_shell` resolves URLs through it. |
//! | [`cn`] | Tailwind class-string merger with shadcn-style conflict resolution. |
//! | [`Signal`], [`register_island`], [`mount_all`], [`init_panic_hook`], [`on_click`], [`on_event`], [`set_class`], [`text_binding`], [`call_action`], [`navigate`] | WASM page-author API (available on both `wasm32-unknown-unknown` and the host target — the rlib path is unconditional). [`navigate`] triggers client-side navigation programmatically (same path as a link click; full-load fallback on error). |
//! | [`action_router`], [`ActionContext`], [`ActionError`], [`ActionRegistry`] *(non-wasm)* | Server-side typed-action plumbing. |
//! | [`cache_layer`] *(non-wasm)* | Tower middleware that sets `Cache-Control` by path pattern and honors `If-None-Match` for 304 responses on static assets. |
//! | [`actions_shared`] | Re-exported sub-crate of pure types shared between server and WASM (request/response shapes). |
//! | `basecoat_core`, `basecoat_components`, `basecoat_css` *(behind the `basecoat` feature)* | shadcn-style UI components and rsx macros, opt-in. |
//!
//! ## Suspense — API shape
//!
//! [`Suspense`] is invoked through rsx interpolation rather than as a literal tag,
//! because the `basecoat-macros` `rsx!` macro auto-routes PascalCase tags to
//! `::basecoat_components::<snake>`. (Consumers that want `rsx!` add `basecoat-macros`
//! as their own direct dependency — `islands` does not pull it for them; see "The
//! `basecoat` feature" below.)
//!
//! ```rust,ignore
//! rsx! {
//!     section class="page" {
//!         { islands::Suspense::new(
//!             rsx! { div class="skeleton h-9 w-32" {} },
//!             async move { island_marker("Counter", &props, body) }
//!         ).render() }
//!     }
//! }
//! ```
//!
//! Suspense is **streaming-only** — it is valid only inside [`render_streaming`] /
//! [`render_streaming_with`]. Using it from a non-streaming render path panics at runtime
//! with `RenderStreamContext not active`. Non-streaming pages should call
//! [`island_marker`] directly.
//!
//! ## The `basecoat` feature
//!
//! `basecoat` is **off by default**. Enabling it pulls in the basecoat UI component layer
//! (`basecoat-core` / `basecoat-components` / `basecoat-css`). The proc-macro layer
//! (`basecoat-macros` + `basecoat-macros-rt`) is **not** pulled by `islands` or
//! `islands-core` at all — a consumer that wants `rsx!` adds those two crates as direct
//! dependencies themselves. This keeps the islands.rs dep tree zero-cost for consumers
//! that only need the SSR primitives and write their HTML another way.
//!
//! When the feature is **on**, `cargo xtask` materializes `assets/css/basecoat.css` with
//! the full basecoat utility classes; when **off**, the same file is written as a 2-line
//! disabled stub so the `@import "./basecoat.css";` in `base.css` always resolves but
//! contributes no rules. Toggle at build time via the `ISLANDS_FEATURES` env var.
//!
//! ## Prelude
//!
//! See the [`prelude`] module for a curated subset of the above suitable for
//! `use islands::prelude::*;` in most pages and server modules.
//!
//! [`plan.md`]: https://github.com/kyureion/islands-rs/blob/main/plan.md

// ---------------------------------------------------------------------------
// Core SSR primitives: markup helpers, manifest, streaming + Suspense.
// ---------------------------------------------------------------------------

pub use islands_core::{
    island_marker, page_shell, page_shell_static, CoreError, Manifest, ManifestEntry,
};

// Streaming SSR + Suspense — behind the `suspense` feature.
#[cfg(feature = "suspense")]
pub use islands_core::{
    page_shell_streaming_head, render_streaming, render_streaming_with, HtmlChunk, StreamError,
    Suspense, REPLACE_SCRIPT,
};

// ---------------------------------------------------------------------------
// CSS utilities: shadcn-style class merging.
// ---------------------------------------------------------------------------

pub use islands_css::cn;

// ---------------------------------------------------------------------------
// Shared action types (request/response shapes used by both server and WASM).
// ---------------------------------------------------------------------------

pub use islands_actions_shared as actions_shared;

// ---------------------------------------------------------------------------
// WASM page-author API. Re-exported on both `wasm32-unknown-unknown` and the
// host target because page crates compile as `["cdylib", "rlib"]` and need the
// rlib path to be visible during `cargo build --workspace` on the native target.
// ---------------------------------------------------------------------------

pub use islands_runtime_bindings::{
    call_action, init_panic_hook, mount_all, on_click, on_event, register_island, set_class,
    text_binding, Signal,
};

// Programmatic client navigation — behind the `nav` feature.
#[cfg(feature = "nav")]
pub use islands_runtime_bindings::navigate;

// ---------------------------------------------------------------------------
// Native-only: server-side action plumbing and Axum integration.
// ---------------------------------------------------------------------------

#[cfg(not(target_arch = "wasm32"))]
pub use islands_actions::{action_router, ActionContext, ActionError, ActionRegistry};

#[cfg(not(target_arch = "wasm32"))]
pub use islands_axum::cache_layer;

// The routes-as-data table — the single source of truth for the router (and, with
// `nav`, the nav manifest). Always available on the server.
#[cfg(not(target_arch = "wasm32"))]
pub use islands_axum::{RouteEntry, RouteTable};

// Client-navigation server surface — behind the `nav` feature: the resolved
// route→bundle nav manifest, the helper that serves it at
// `/static/nav-manifest.json`, and the `X-Islands-Nav` content-negotiation
// detector a streaming route handler uses to render an island marker inline for a
// morph-nav fetch instead of as a `<template>` skeleton (AC-V13).
#[cfg(all(not(target_arch = "wasm32"), feature = "nav"))]
pub use islands_axum::{
    is_nav_request, nav_manifest_router, NavManifest, NavRoute, NAV_MANIFEST_PATH,
    NAV_REQUEST_HEADER, NAV_REQUEST_VALUE,
};

// ---------------------------------------------------------------------------
// Optional basecoat UI layer. Gated by `basecoat` feature (off by default).
// `basecoat-macros` + `basecoat-macros-rt` are NOT here and are NOT pulled by
// `islands-core` either — a consumer that wants `rsx!` declares them as their
// own direct dependencies (proc-macros can't be transparently re-exported, so
// the explicit declaration was always required anyway).
// ---------------------------------------------------------------------------

#[cfg(feature = "basecoat")]
pub use basecoat_core;
#[cfg(feature = "basecoat")]
pub use basecoat_components;
#[cfg(feature = "basecoat")]
pub use basecoat_css;

/// Curated re-exports for `use islands::prelude::*;`.
///
/// Includes everything a typical page or server-side route handler needs without pulling
/// in less common types (`CoreError`, `StreamError`, `HtmlChunk`, `REPLACE_SCRIPT`,
/// `render_streaming_with`, etc. remain accessible via the crate root for the cases
/// that genuinely need them).
///
/// The prelude is target-aware:
/// - `wasm32-unknown-unknown`: page-author bindings (`Signal`, `on_click`, ...) plus the
///   core markup + Suspense types so SSR seed paths can call the same helpers.
/// - native: everything in the wasm prelude PLUS the server-side action types and the
///   `cache_layer` tower middleware.
pub mod prelude {
    pub use islands_core::island_marker;
    pub use islands_core::page_shell;
    pub use islands_core::page_shell_static;
    pub use islands_core::Manifest;
    #[cfg(feature = "suspense")]
    pub use islands_core::page_shell_streaming_head;
    #[cfg(feature = "suspense")]
    pub use islands_core::Suspense;

    pub use islands_css::cn;

    pub use islands_runtime_bindings::call_action;
    pub use islands_runtime_bindings::init_panic_hook;
    pub use islands_runtime_bindings::mount_all;
    pub use islands_runtime_bindings::on_click;
    pub use islands_runtime_bindings::on_event;
    pub use islands_runtime_bindings::register_island;
    pub use islands_runtime_bindings::set_class;
    pub use islands_runtime_bindings::text_binding;
    pub use islands_runtime_bindings::Signal;
    #[cfg(feature = "nav")]
    pub use islands_runtime_bindings::navigate;

    #[cfg(not(target_arch = "wasm32"))]
    pub use islands_actions::action_router;
    #[cfg(not(target_arch = "wasm32"))]
    pub use islands_actions::ActionContext;
    #[cfg(not(target_arch = "wasm32"))]
    pub use islands_actions::ActionError;
    #[cfg(not(target_arch = "wasm32"))]
    pub use islands_actions::ActionRegistry;

    #[cfg(not(target_arch = "wasm32"))]
    pub use islands_axum::cache_layer;
    #[cfg(not(target_arch = "wasm32"))]
    pub use islands_axum::RouteTable;

    #[cfg(all(not(target_arch = "wasm32"), feature = "nav"))]
    pub use islands_axum::nav_manifest_router;
    #[cfg(all(not(target_arch = "wasm32"), feature = "nav"))]
    pub use islands_axum::NavManifest;
}
