///|
/// Convert @http.RequestMethod to @router.Method
fn request_method_to_method(meth : @http.RequestMethod) -> @router.Method {
  match meth {
    Get => @router.Method::Get
    Post => @router.Method::Post
    Put => @router.Method::Put
    Delete => @router.Method::Delete
    Patch => @router.Method::Patch
    Head => @router.Method::Head
    Options => @router.Method::Options
    Connect => @router.Method::Connect
    Trace => @router.Method::Trace
  }
}

///|
pub type AppHandler = async (
  @http.Request,
  &@async_io.Reader,
  @http.ServerConnection,
) -> Unit

///|
/// Convert Server app to a platform handler function (native only)
pub fn Server::to_handler(self : Server) -> AppHandler {
  self.to_handler_with_env(EmptyEnv::new(), ExecutionContext::new())
}

///|
/// Convert Server app to a platform handler function with environment and execution context (native only)
pub fn[E : Env, C : ExecCtx] Server::to_handler_with_env(
  self : Server,
  env : E,
  exec_ctx : C,
) -> AppHandler {
  async fn(request, body, conn) {
    let meth = request_method_to_method(request.meth)
    let routing_path = strip_query_string(request.path)
    match
      self.match_and_dispatch(meth, routing_path, fn(params) {
        Context::with_env(request, params, conn, body, env, exec_ctx)
      }) {
      RequestDispatchResult::NotFound => {
        conn.send_response(404, "Not Found")
        conn.end_response()
      }
      RequestDispatchResult::Dispatched(dispatch) =>
        match dispatch_fallback_status(dispatch) {
          Some(500) => {
            conn.send_response(500, "Internal Server Error")
            conn.end_response()
          }
          Some(404) => {
            conn.send_response(404, "Not Found")
            conn.end_response()
          }
          _ => ()
        }
    }

    // Run background tasks after response is sent
    // Note: exec_ctx is a trait object, so we need to check if it's ExecutionContext
    // For now, background tasks are handled by the ExecCtx implementation
  }
}

///|
/// Start the HTTP server
pub async fn Server::serve(self : Server, host? : String, port? : Int) -> Unit {
  self.serve_with_env(host?, port?, EmptyEnv::new(), ExecutionContext::new())
}

///|
/// Start the HTTP server with environment and execution context
pub async fn[E : Env, C : ExecCtx] Server::serve_with_env(
  self : Server,
  host? : String,
  port? : Int,
  env : E,
  exec_ctx : C,
) -> Unit {
  let server = @http.Server::new(host?, port?)
  let handler = self.to_handler_with_env(env, exec_ctx)
  server.run_forever(handler)
}