// HTTP transport seam.
//
// This package never speaks HTTP itself: it turns Exa API calls into
// `HttpRequest` values and hands them to a `Transport`. That keeps the client
// buildable on every backend and testable without a network. See the
// `marianoguerra/exa/async_http` package for a transport backed by
// `moonbitlang/async/http`.

///|
/// A single HTTP request, fully rendered and ready to send.
pub(all) struct HttpRequest {
  meth : String
  url : String
  headers : Array[(String, String)]
  body : String
} derive(Eq, @debug.Debug)

///|
/// The response to an `HttpRequest`.
pub(all) struct HttpResponse {
  status : Int
  headers : Array[(String, String)]
  body : String
} derive(Eq, @debug.Debug)

///|
/// Look up a response header, case-insensitively.
pub fn HttpResponse::header(self : HttpResponse, name : String) -> String? {
  let wanted = name.to_lower()
  for kv in self.headers {
    if kv.0.to_lower() == wanted {
      return Some(kv.1)
    }
  }
  None
}

///|
/// Anything that can perform an HTTP request.
pub(open) trait Transport {
  async fn send(Self, HttpRequest) -> HttpResponse
}