/*
 * rivet-api-public
 *
 * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
 *
 * The version of the OpenAPI document: 2.3.0-rc.11
 * Contact: developer@rivet.gg
 * Generated by: https://openapi-generator.tech
 */


use reqwest;
use serde::{Deserialize, Serialize, de::Error as _};
use crate::{apis::ResponseContent, models};
use super::{Error, configuration, ContentType};


/// struct for typed errors of method [`actors_list`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum ActorsListError {
    UnknownValue(serde_json::Value),
}


///  **If key is some & `include_destroyed` is false**   2 round trips:  - namespace::ops::resolve_for_name_global  - GET /actors (multiple DCs based on actor IDs)   This path is optimized because we can read the actor IDs fro the key directly from Epoxy with  stale consistency to determine which datacenter the actor lives in. Under most circumstances,  this means we don't need to fan out to all datacenters (like normal list does).   The reason `include_destroyed` has to be false is Epoxy only stores currently active actors. If  `include_destroyed` is true, we show all previous iterations of actors with the same key.   **Otherwise**   2 round trips:  - namespace::ops::resolve_for_name_global  - GET /actors (fanout)   ## Optimized Alternative Routes
pub async fn actors_list(configuration: &configuration::Configuration, namespace: &str, name: Option<&str>, key: Option<&str>, actor_ids: Option<&str>, actor_id: Option<Vec<String>>, include_destroyed: Option<bool>, limit: Option<i32>, cursor: Option<&str>) -> Result<models::ActorsListResponse, Error<ActorsListError>> {
    // add a prefix to parameters to efficiently prevent name collisions
    let p_namespace = namespace;
    let p_name = name;
    let p_key = key;
    let p_actor_ids = actor_ids;
    let p_actor_id = actor_id;
    let p_include_destroyed = include_destroyed;
    let p_limit = limit;
    let p_cursor = cursor;

    let uri_str = format!("{}/actors", configuration.base_path);
    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);

    req_builder = req_builder.query(&[("namespace", &p_namespace.to_string())]);
    if let Some(ref param_value) = p_name {
        req_builder = req_builder.query(&[("name", &param_value.to_string())]);
    }
    if let Some(ref param_value) = p_key {
        req_builder = req_builder.query(&[("key", &param_value.to_string())]);
    }
    if let Some(ref param_value) = p_actor_ids {
        req_builder = req_builder.query(&[("actor_ids", &param_value.to_string())]);
    }
    if let Some(ref param_value) = p_actor_id {
        req_builder = match "multi" {
            "multi" => req_builder.query(&param_value.into_iter().map(|p| ("actor_id".to_owned(), p.to_string())).collect::<Vec<(std::string::String, std::string::String)>>()),
            _ => req_builder.query(&[("actor_id", &param_value.into_iter().map(|p| p.to_string()).collect::<Vec<String>>().join(",").to_string())]),
        };
    }
    if let Some(ref param_value) = p_include_destroyed {
        req_builder = req_builder.query(&[("include_destroyed", &param_value.to_string())]);
    }
    if let Some(ref param_value) = p_limit {
        req_builder = req_builder.query(&[("limit", &param_value.to_string())]);
    }
    if let Some(ref param_value) = p_cursor {
        req_builder = req_builder.query(&[("cursor", &param_value.to_string())]);
    }
    if let Some(ref user_agent) = configuration.user_agent {
        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
    }
    if let Some(ref token) = configuration.bearer_access_token {
        req_builder = req_builder.bearer_auth(token.to_owned());
    };

    let req = req_builder.build()?;
    let resp = configuration.client.execute(req).await?;

    let status = resp.status();
    let content_type = resp
        .headers()
        .get("content-type")
        .and_then(|v| v.to_str().ok())
        .unwrap_or("application/octet-stream");
    let content_type = super::ContentType::from(content_type);

    if !status.is_client_error() && !status.is_server_error() {
        let content = resp.text().await?;
        match content_type {
            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::ActorsListResponse`"))),
            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::ActorsListResponse`")))),
        }
    } else {
        let content = resp.text().await?;
        let entity: Option<ActorsListError> = serde_json::from_str(&content).ok();
        Err(Error::ResponseError(ResponseContent { status, content, entity }))
    }
}

