package wang.yaojia.webterm.wire

/**
 * Thin HTTP I/O boundary (FROZEN contract, plan §3.1). The Android analogue of iOS
 * `WireProtocol.HTTPTransport`. `:api-client` (A8/A9) builds [HttpRequest]s (stamping `Origin`
 * IFF the route is a mutating/guarded one, plan §4.3) and sends them through this seam;
 * `:transport-okhttp` (A7) implements it over OkHttp, the fake in `:test-support` (A3) queues
 * canned responses. Pure interface — the request/response DTOs are OkHttp-free so both sides
 * share them without an Android dependency.
 */
public interface HttpTransport {
    /**
     * Perform one HTTP exchange. Implementations throw on transport-level failure; a non-2xx
     * status is RETURNED (not thrown) — classification (e.g. `PairingError`) is the caller's job.
     */
    public suspend fun send(request: HttpRequest): HttpResponse
}

/** HTTP verbs used by the client surface (`src/http` routes: GET reads, POST/PUT/DELETE guarded). */
public enum class HttpMethod {
    GET,
    POST,
    PUT,
    DELETE,
}

/**
 * A pure HTTP request DTO built by `:api-client`. [headers] carries `Origin` only for guarded
 * routes (plan §4.3 铁律). [body] is opaque bytes (JSON for the mutating routes); null for GET.
 *
 * NOTE: [body] is a `ByteArray`, so generated equality is by reference — these are transient
 * I/O carriers, not value-equality keys.
 */
public data class HttpRequest(
    val method: HttpMethod,
    val url: String,
    val headers: Map<String, String> = emptyMap(),
    val body: ByteArray? = null,
)

/**
 * A pure HTTP response DTO. [status] is the HTTP status code (204/404/403/429 all meaningful
 * to callers — see plan §4.2/§4.3); [body] is the raw bytes (may be empty for 204).
 *
 * NOTE: [body] is a `ByteArray`, so generated equality is by reference — see [HttpRequest].
 */
public data class HttpResponse(
    val status: Int,
    val body: ByteArray,
    val headers: Map<String, String> = emptyMap(),
)
