//!
//! AUTO-GENERATED CODE - DO NOT EDIT!
//!
//! Swagger Petstore
//! Source: crates/oas3-gen/fixtures/petstore.json
//! Version: 1.0.0
//! Generated by `oas3-gen v0.26.0`
//!

use axum::{
  Router,
  extract::{Path, Query, State},
  http::HeaderMap,
  response::IntoResponse,
  routing::{get, post},
};

use super::types::*;
pub trait ApiServer: Send + Sync {
  /// List all pets
  ///
  /// * Path: `GET /{api_version}/pets`
  fn list_pets(
    &self,
    request: ListPetsRequest,
  ) -> impl std::future::Future<Output = anyhow::Result<ListPetsResponse>> + Send;
  /// Create a pet
  ///
  /// * Path: `POST /{api_version}/pets`
  fn create_pets(
    &self,
    request: CreatePetsRequest,
  ) -> impl std::future::Future<Output = anyhow::Result<CreatePetsResponse>> + Send;
  /// List all cats
  ///
  /// * Path: `GET /cats`
  fn list_cats(
    &self,
    request: ListCatsRequest,
  ) -> impl std::future::Future<Output = anyhow::Result<ListCatsResponse>> + Send;
  /// Info for a specific pet
  ///
  /// * Path: `GET /pets/{petId}`
  fn show_pet_by_id(
    &self,
    request: ShowPetByIdRequest,
  ) -> impl std::future::Future<Output = anyhow::Result<ShowPetByIdResponse>> + Send;
  /// Upload pet image and update name
  ///
  /// * Path: `POST /pets/{petId}/upload`
  fn upload_pet_image(
    &self,
    request: UploadPetImageRequest,
  ) -> impl std::future::Future<Output = anyhow::Result<ShowPetByIdResponse>> + Send;
}
pub async fn list_pets<S>(
  State(service): State<S>,
  Path(path): Path<ListPetsRequestPath>,
  Query(query): Query<ListPetsRequestQuery>,
  headers: HeaderMap,
) -> impl IntoResponse
where
  S: ApiServer + Clone + Send + Sync + 'static,
{
  let request = ListPetsRequest {
    path,
    query,
    header: (&headers).try_into().unwrap_or_default(),
  };
  let result: anyhow::Result<ListPetsResponse> = service.list_pets(request).await;
  match result {
    Ok(response) => response.into_response(),
    Err(e) => (
      axum::http::StatusCode::INTERNAL_SERVER_ERROR,
      format!("Internal error: {e}"),
    )
      .into_response(),
  }
}
pub async fn create_pets<S>(State(service): State<S>, Path(path): Path<CreatePetsRequestPath>) -> impl IntoResponse
where
  S: ApiServer + Clone + Send + Sync + 'static,
{
  let request = CreatePetsRequest { path };
  let result: anyhow::Result<CreatePetsResponse> = service.create_pets(request).await;
  match result {
    Ok(response) => response.into_response(),
    Err(e) => (
      axum::http::StatusCode::INTERNAL_SERVER_ERROR,
      format!("Internal error: {e}"),
    )
      .into_response(),
  }
}
pub async fn list_cats<S>(
  State(service): State<S>,
  Query(query): Query<ListCatsRequestQuery>,
  headers: HeaderMap,
) -> impl IntoResponse
where
  S: ApiServer + Clone + Send + Sync + 'static,
{
  let request = ListCatsRequest {
    query,
    header: (&headers).try_into().unwrap_or_default(),
  };
  let result: anyhow::Result<ListCatsResponse> = service.list_cats(request).await;
  match result {
    Ok(response) => response.into_response(),
    Err(e) => (
      axum::http::StatusCode::INTERNAL_SERVER_ERROR,
      format!("Internal error: {e}"),
    )
      .into_response(),
  }
}
pub async fn show_pet_by_id<S>(
  State(service): State<S>,
  Path(path): Path<ShowPetByIdRequestPath>,
  headers: HeaderMap,
) -> impl IntoResponse
where
  S: ApiServer + Clone + Send + Sync + 'static,
{
  let request = ShowPetByIdRequest {
    path,
    header: (&headers).try_into().unwrap_or_default(),
  };
  let result: anyhow::Result<ShowPetByIdResponse> = service.show_pet_by_id(request).await;
  match result {
    Ok(response) => response.into_response(),
    Err(e) => (
      axum::http::StatusCode::INTERNAL_SERVER_ERROR,
      format!("Internal error: {e}"),
    )
      .into_response(),
  }
}
pub async fn upload_pet_image<S>(
  State(service): State<S>,
  Path(path): Path<UploadPetImageRequestPath>,
  axum::Json(body): axum::Json<UploadRequestBody>,
) -> impl IntoResponse
where
  S: ApiServer + Clone + Send + Sync + 'static,
{
  let request = UploadPetImageRequest { path, body };
  let result: anyhow::Result<ShowPetByIdResponse> = service.upload_pet_image(request).await;
  match result {
    Ok(response) => response.into_response(),
    Err(e) => (
      axum::http::StatusCode::INTERNAL_SERVER_ERROR,
      format!("Internal error: {e}"),
    )
      .into_response(),
  }
}
pub fn router<S>(service: S) -> Router
where
  S: ApiServer + Clone + Send + Sync + 'static,
{
  Router::new()
    .route("/{api_version}/pets", get(list_pets::<S>).post(create_pets::<S>))
    .route("/cats", get(list_cats::<S>))
    .route("/pets/{pet_id}", get(show_pet_by_id::<S>))
    .route("/pets/{pet_id}/upload", post(upload_pet_image::<S>))
    .with_state(service)
}
