/*
 * Tapis Applications API
 *
 * The Tapis Applications API provides for management of Tapis applications including permissions.
 *
 * The version of the OpenAPI document: 26Q1.0
 * Contact: cicsupport@tacc.utexas.edu
 * Generated by: https://openapi-generator.tech
 */

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

/// struct for typed errors of method [`change_app_owner`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum ChangeAppOwnerError {
    Status403(models::RespBasic),
    Status404(models::RespBasic),
    Status500(models::RespBasic),
    UnknownValue(serde_json::Value),
}

/// struct for typed errors of method [`create_app_version`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum CreateAppVersionError {
    Status400(models::RespBasic),
    Status403(models::RespBasic),
    Status409(models::RespResourceUrl),
    Status500(models::RespBasic),
    UnknownValue(serde_json::Value),
}

/// struct for typed errors of method [`delete_app`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum DeleteAppError {
    Status403(models::RespBasic),
    Status404(models::RespBasic),
    Status500(models::RespBasic),
    UnknownValue(serde_json::Value),
}

/// struct for typed errors of method [`disable_app`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum DisableAppError {
    Status403(models::RespBasic),
    Status404(models::RespBasic),
    Status500(models::RespBasic),
    UnknownValue(serde_json::Value),
}

/// struct for typed errors of method [`disable_app_version`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum DisableAppVersionError {
    Status403(models::RespBasic),
    Status404(models::RespBasic),
    Status500(models::RespBasic),
    UnknownValue(serde_json::Value),
}

/// struct for typed errors of method [`enable_app`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum EnableAppError {
    Status403(models::RespBasic),
    Status404(models::RespBasic),
    Status500(models::RespBasic),
    UnknownValue(serde_json::Value),
}

/// struct for typed errors of method [`enable_app_version`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum EnableAppVersionError {
    Status403(models::RespBasic),
    Status404(models::RespBasic),
    Status500(models::RespBasic),
    UnknownValue(serde_json::Value),
}

/// struct for typed errors of method [`get_app`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum GetAppError {
    Status400(models::RespBasic),
    Status403(models::RespBasic),
    Status404(models::RespBasic),
    Status500(models::RespBasic),
    UnknownValue(serde_json::Value),
}

/// struct for typed errors of method [`get_app_latest_version`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum GetAppLatestVersionError {
    Status400(models::RespBasic),
    Status403(models::RespBasic),
    Status404(models::RespBasic),
    Status500(models::RespBasic),
    UnknownValue(serde_json::Value),
}

/// struct for typed errors of method [`get_apps`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum GetAppsError {
    Status400(models::RespBasic),
    Status500(models::RespBasic),
    UnknownValue(serde_json::Value),
}

/// struct for typed errors of method [`get_history`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum GetHistoryError {
    Status403(models::RespBasic),
    Status404(models::RespBasic),
    Status500(models::RespBasic),
    UnknownValue(serde_json::Value),
}

/// struct for typed errors of method [`is_enabled`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum IsEnabledError {
    Status403(models::RespBasic),
    Status404(models::RespBasic),
    Status500(models::RespBasic),
    UnknownValue(serde_json::Value),
}

/// struct for typed errors of method [`lock_app`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum LockAppError {
    Status403(models::RespBasic),
    Status404(models::RespBasic),
    Status500(models::RespBasic),
    UnknownValue(serde_json::Value),
}

/// struct for typed errors of method [`patch_app`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum PatchAppError {
    Status400(models::RespBasic),
    Status403(models::RespBasic),
    Status404(models::RespBasic),
    Status500(models::RespBasic),
    UnknownValue(serde_json::Value),
}

/// struct for typed errors of method [`put_app`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum PutAppError {
    Status400(models::RespBasic),
    Status403(models::RespBasic),
    Status404(models::RespBasic),
    Status409(models::RespResourceUrl),
    Status500(models::RespBasic),
    UnknownValue(serde_json::Value),
}

/// struct for typed errors of method [`search_apps_query_parameters`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum SearchAppsQueryParametersError {
    Status400(models::RespBasic),
    Status500(models::RespBasic),
    UnknownValue(serde_json::Value),
}

/// struct for typed errors of method [`search_apps_request_body`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum SearchAppsRequestBodyError {
    Status400(models::RespBasic),
    Status500(models::RespBasic),
    UnknownValue(serde_json::Value),
}

/// struct for typed errors of method [`undelete_app`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum UndeleteAppError {
    Status403(models::RespBasic),
    Status404(models::RespBasic),
    Status500(models::RespBasic),
    UnknownValue(serde_json::Value),
}

/// struct for typed errors of method [`unlock_app`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum UnlockAppError {
    Status403(models::RespBasic),
    Status404(models::RespBasic),
    Status500(models::RespBasic),
    UnknownValue(serde_json::Value),
}

/// Change owner of an application. Applies to all versions.
pub async fn change_app_owner(
    configuration: &configuration::Configuration,
    app_id: &str,
    user_name: &str,
) -> Result<models::RespChangeCount, Error<ChangeAppOwnerError>> {
    // add a prefix to parameters to efficiently prevent name collisions
    let p_path_app_id = app_id;
    let p_path_user_name = user_name;

    let uri_str = format!(
        "{}/v3/apps/{appId}/changeOwner/{userName}",
        configuration.base_path,
        appId = crate::apis::urlencode(p_path_app_id),
        userName = crate::apis::urlencode(p_path_user_name)
    );
    let mut req_builder = configuration
        .client
        .request(reqwest::Method::POST, &uri_str);

    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 apikey) = configuration.api_key {
        let key = apikey.key.clone();
        let value = match apikey.prefix {
            Some(ref prefix) => format!("{} {}", prefix, key),
            None => key,
        };
        req_builder = req_builder.header("X-Tapis-Token", value);
    };

    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 => Err(Error::from(serde_json::Error::custom(
                "Received `text/plain` content type response that cannot be converted to `models::RespChangeCount`",
            ))),
            ContentType::Unsupported(unknown_type) => {
                Err(Error::from(serde_json::Error::custom(format!(
                    "Received `{unknown_type}` content type response that cannot be converted to `models::RespChangeCount`"
                ))))
            }
        }
    } else {
        let content = resp.text().await?;
        let entity: Option<ChangeAppOwnerError> = serde_json::from_str(&content).ok();
        Err(Error::ResponseError(ResponseContent {
            status,
            content,
            entity,
        }))
    }
}

/// Create an application using a request body. App id+version must be unique within tenant and can be composed of alphanumeric characters and the following special characters [-._~]. Id must begin with an alphanumeric character and can be no more than 80 characters in length.  Note that certain attributes (such as tenant) are allowed but ignored so that the JSON result returned by a GET may be modified and used when making a POST request to create an application. The attributes that are allowed but ignored are    - tenant   - uuid   - isPublic   - sharedWithUsers   - sharedAppCtx   - deleted   - created   - updated
pub async fn create_app_version(
    configuration: &configuration::Configuration,
    req_post_app: models::ReqPostApp,
) -> Result<models::RespResourceUrl, Error<CreateAppVersionError>> {
    // add a prefix to parameters to efficiently prevent name collisions
    let p_body_req_post_app = req_post_app;

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

    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 apikey) = configuration.api_key {
        let key = apikey.key.clone();
        let value = match apikey.prefix {
            Some(ref prefix) => format!("{} {}", prefix, key),
            None => key,
        };
        req_builder = req_builder.header("X-Tapis-Token", value);
    };
    req_builder = req_builder.json(&p_body_req_post_app);

    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 => Err(Error::from(serde_json::Error::custom(
                "Received `text/plain` content type response that cannot be converted to `models::RespResourceUrl`",
            ))),
            ContentType::Unsupported(unknown_type) => {
                Err(Error::from(serde_json::Error::custom(format!(
                    "Received `{unknown_type}` content type response that cannot be converted to `models::RespResourceUrl`"
                ))))
            }
        }
    } else {
        let content = resp.text().await?;
        let entity: Option<CreateAppVersionError> = serde_json::from_str(&content).ok();
        Err(Error::ResponseError(ResponseContent {
            status,
            content,
            entity,
        }))
    }
}

/// Mark an application as deleted. Application will not appear in queries unless explicitly requested.
pub async fn delete_app(
    configuration: &configuration::Configuration,
    app_id: &str,
) -> Result<models::RespChangeCount, Error<DeleteAppError>> {
    // add a prefix to parameters to efficiently prevent name collisions
    let p_path_app_id = app_id;

    let uri_str = format!(
        "{}/v3/apps/{appId}/delete",
        configuration.base_path,
        appId = crate::apis::urlencode(p_path_app_id)
    );
    let mut req_builder = configuration
        .client
        .request(reqwest::Method::POST, &uri_str);

    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 apikey) = configuration.api_key {
        let key = apikey.key.clone();
        let value = match apikey.prefix {
            Some(ref prefix) => format!("{} {}", prefix, key),
            None => key,
        };
        req_builder = req_builder.header("X-Tapis-Token", value);
    };

    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 => Err(Error::from(serde_json::Error::custom(
                "Received `text/plain` content type response that cannot be converted to `models::RespChangeCount`",
            ))),
            ContentType::Unsupported(unknown_type) => {
                Err(Error::from(serde_json::Error::custom(format!(
                    "Received `{unknown_type}` content type response that cannot be converted to `models::RespChangeCount`"
                ))))
            }
        }
    } else {
        let content = resp.text().await?;
        let entity: Option<DeleteAppError> = serde_json::from_str(&content).ok();
        Err(Error::ResponseError(ResponseContent {
            status,
            content,
            entity,
        }))
    }
}

/// Mark an application unavailable for use. Applies to all versions. Requester must be owner of the app or a tenant administrator.
pub async fn disable_app(
    configuration: &configuration::Configuration,
    app_id: &str,
) -> Result<models::RespChangeCount, Error<DisableAppError>> {
    // add a prefix to parameters to efficiently prevent name collisions
    let p_path_app_id = app_id;

    let uri_str = format!(
        "{}/v3/apps/{appId}/disable",
        configuration.base_path,
        appId = crate::apis::urlencode(p_path_app_id)
    );
    let mut req_builder = configuration
        .client
        .request(reqwest::Method::POST, &uri_str);

    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 apikey) = configuration.api_key {
        let key = apikey.key.clone();
        let value = match apikey.prefix {
            Some(ref prefix) => format!("{} {}", prefix, key),
            None => key,
        };
        req_builder = req_builder.header("X-Tapis-Token", value);
    };

    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 => Err(Error::from(serde_json::Error::custom(
                "Received `text/plain` content type response that cannot be converted to `models::RespChangeCount`",
            ))),
            ContentType::Unsupported(unknown_type) => {
                Err(Error::from(serde_json::Error::custom(format!(
                    "Received `{unknown_type}` content type response that cannot be converted to `models::RespChangeCount`"
                ))))
            }
        }
    } else {
        let content = resp.text().await?;
        let entity: Option<DisableAppError> = serde_json::from_str(&content).ok();
        Err(Error::ResponseError(ResponseContent {
            status,
            content,
            entity,
        }))
    }
}

/// Mark a specific version of an application unavailable for use. Requester must be owner of the app or a tenant administrator.
pub async fn disable_app_version(
    configuration: &configuration::Configuration,
    app_id: &str,
    app_version: &str,
) -> Result<models::RespChangeCount, Error<DisableAppVersionError>> {
    // add a prefix to parameters to efficiently prevent name collisions
    let p_path_app_id = app_id;
    let p_path_app_version = app_version;

    let uri_str = format!(
        "{}/v3/apps/{appId}/{appVersion}/disable",
        configuration.base_path,
        appId = crate::apis::urlencode(p_path_app_id),
        appVersion = crate::apis::urlencode(p_path_app_version)
    );
    let mut req_builder = configuration
        .client
        .request(reqwest::Method::POST, &uri_str);

    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 apikey) = configuration.api_key {
        let key = apikey.key.clone();
        let value = match apikey.prefix {
            Some(ref prefix) => format!("{} {}", prefix, key),
            None => key,
        };
        req_builder = req_builder.header("X-Tapis-Token", value);
    };

    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 => Err(Error::from(serde_json::Error::custom(
                "Received `text/plain` content type response that cannot be converted to `models::RespChangeCount`",
            ))),
            ContentType::Unsupported(unknown_type) => {
                Err(Error::from(serde_json::Error::custom(format!(
                    "Received `{unknown_type}` content type response that cannot be converted to `models::RespChangeCount`"
                ))))
            }
        }
    } else {
        let content = resp.text().await?;
        let entity: Option<DisableAppVersionError> = serde_json::from_str(&content).ok();
        Err(Error::ResponseError(ResponseContent {
            status,
            content,
            entity,
        }))
    }
}

/// Mark an application available for use. Applies to all versions. Requester must be owner of the app or a tenant administrator.
pub async fn enable_app(
    configuration: &configuration::Configuration,
    app_id: &str,
) -> Result<models::RespChangeCount, Error<EnableAppError>> {
    // add a prefix to parameters to efficiently prevent name collisions
    let p_path_app_id = app_id;

    let uri_str = format!(
        "{}/v3/apps/{appId}/enable",
        configuration.base_path,
        appId = crate::apis::urlencode(p_path_app_id)
    );
    let mut req_builder = configuration
        .client
        .request(reqwest::Method::POST, &uri_str);

    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 apikey) = configuration.api_key {
        let key = apikey.key.clone();
        let value = match apikey.prefix {
            Some(ref prefix) => format!("{} {}", prefix, key),
            None => key,
        };
        req_builder = req_builder.header("X-Tapis-Token", value);
    };

    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 => Err(Error::from(serde_json::Error::custom(
                "Received `text/plain` content type response that cannot be converted to `models::RespChangeCount`",
            ))),
            ContentType::Unsupported(unknown_type) => {
                Err(Error::from(serde_json::Error::custom(format!(
                    "Received `{unknown_type}` content type response that cannot be converted to `models::RespChangeCount`"
                ))))
            }
        }
    } else {
        let content = resp.text().await?;
        let entity: Option<EnableAppError> = serde_json::from_str(&content).ok();
        Err(Error::ResponseError(ResponseContent {
            status,
            content,
            entity,
        }))
    }
}

/// Mark a specific version of an application available for use. Requester must be owner of the app or a tenant administrator.
pub async fn enable_app_version(
    configuration: &configuration::Configuration,
    app_id: &str,
    app_version: &str,
) -> Result<models::RespChangeCount, Error<EnableAppVersionError>> {
    // add a prefix to parameters to efficiently prevent name collisions
    let p_path_app_id = app_id;
    let p_path_app_version = app_version;

    let uri_str = format!(
        "{}/v3/apps/{appId}/{appVersion}/enable",
        configuration.base_path,
        appId = crate::apis::urlencode(p_path_app_id),
        appVersion = crate::apis::urlencode(p_path_app_version)
    );
    let mut req_builder = configuration
        .client
        .request(reqwest::Method::POST, &uri_str);

    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 apikey) = configuration.api_key {
        let key = apikey.key.clone();
        let value = match apikey.prefix {
            Some(ref prefix) => format!("{} {}", prefix, key),
            None => key,
        };
        req_builder = req_builder.header("X-Tapis-Token", value);
    };

    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 => Err(Error::from(serde_json::Error::custom(
                "Received `text/plain` content type response that cannot be converted to `models::RespChangeCount`",
            ))),
            ContentType::Unsupported(unknown_type) => {
                Err(Error::from(serde_json::Error::custom(format!(
                    "Received `{unknown_type}` content type response that cannot be converted to `models::RespChangeCount`"
                ))))
            }
        }
    } else {
        let content = resp.text().await?;
        let entity: Option<EnableAppVersionError> = serde_json::from_str(&content).ok();
        Err(Error::ResponseError(ResponseContent {
            status,
            content,
            entity,
        }))
    }
}

/// Retrieve information for an application given the application Id and version. In the result the attribute *sharedAppCtx* indicates if the application is available to the user because it has been shared with the user. The value of *sharedAppCtx* will be the grantor, the Tapis user who shared the application.  Certain Tapis services or a tenant administrator may use the query parameter *impersonationId* to be used in place of the requesting Tapis user. Tapis will use this user Id when performing authorization.
pub async fn get_app(
    configuration: &configuration::Configuration,
    app_id: &str,
    app_version: &str,
    require_exec_perm: Option<bool>,
    impersonation_id: Option<&str>,
    select: Option<&str>,
    resource_tenant: Option<&str>,
) -> Result<models::RespApp, Error<GetAppError>> {
    // add a prefix to parameters to efficiently prevent name collisions
    let p_path_app_id = app_id;
    let p_path_app_version = app_version;
    let p_query_require_exec_perm = require_exec_perm;
    let p_query_impersonation_id = impersonation_id;
    let p_query_select = select;
    let p_query_resource_tenant = resource_tenant;

    let uri_str = format!(
        "{}/v3/apps/{appId}/{appVersion}",
        configuration.base_path,
        appId = crate::apis::urlencode(p_path_app_id),
        appVersion = crate::apis::urlencode(p_path_app_version)
    );
    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);

    if let Some(ref param_value) = p_query_require_exec_perm {
        req_builder = req_builder.query(&[("requireExecPerm", &param_value.to_string())]);
    }
    if let Some(ref param_value) = p_query_impersonation_id {
        req_builder = req_builder.query(&[("impersonationId", &param_value.to_string())]);
    }
    if let Some(ref param_value) = p_query_select {
        req_builder = req_builder.query(&[("select", &param_value.to_string())]);
    }
    if let Some(ref param_value) = p_query_resource_tenant {
        req_builder = req_builder.query(&[("resourceTenant", &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 apikey) = configuration.api_key {
        let key = apikey.key.clone();
        let value = match apikey.prefix {
            Some(ref prefix) => format!("{} {}", prefix, key),
            None => key,
        };
        req_builder = req_builder.header("X-Tapis-Token", value);
    };

    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 => Err(Error::from(serde_json::Error::custom(
                "Received `text/plain` content type response that cannot be converted to `models::RespApp`",
            ))),
            ContentType::Unsupported(unknown_type) => {
                Err(Error::from(serde_json::Error::custom(format!(
                    "Received `{unknown_type}` content type response that cannot be converted to `models::RespApp`"
                ))))
            }
        }
    } else {
        let content = resp.text().await?;
        let entity: Option<GetAppError> = serde_json::from_str(&content).ok();
        Err(Error::ResponseError(ResponseContent {
            status,
            content,
            entity,
        }))
    }
}

/// Retrieve latest version of an application. In the result the attribute *sharedAppCtx* indicates if the application is available to the user because it has been shared with the user. The value of *sharedAppCtx* will be the grantor, the Tapis user who shared the application.  Certain Tapis services or a tenant administrator may use the query parameter *impersonationId* to be used in place of the requesting Tapis user. Tapis will use this user Id when performing authorization.
pub async fn get_app_latest_version(
    configuration: &configuration::Configuration,
    app_id: &str,
    require_exec_perm: Option<bool>,
    select: Option<&str>,
    resource_tenant: Option<&str>,
    impersonation_id: Option<&str>,
) -> Result<models::RespApp, Error<GetAppLatestVersionError>> {
    // add a prefix to parameters to efficiently prevent name collisions
    let p_path_app_id = app_id;
    let p_query_require_exec_perm = require_exec_perm;
    let p_query_select = select;
    let p_query_resource_tenant = resource_tenant;
    let p_query_impersonation_id = impersonation_id;

    let uri_str = format!(
        "{}/v3/apps/{appId}",
        configuration.base_path,
        appId = crate::apis::urlencode(p_path_app_id)
    );
    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);

    if let Some(ref param_value) = p_query_require_exec_perm {
        req_builder = req_builder.query(&[("requireExecPerm", &param_value.to_string())]);
    }
    if let Some(ref param_value) = p_query_select {
        req_builder = req_builder.query(&[("select", &param_value.to_string())]);
    }
    if let Some(ref param_value) = p_query_resource_tenant {
        req_builder = req_builder.query(&[("resourceTenant", &param_value.to_string())]);
    }
    if let Some(ref param_value) = p_query_impersonation_id {
        req_builder = req_builder.query(&[("impersonationId", &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 apikey) = configuration.api_key {
        let key = apikey.key.clone();
        let value = match apikey.prefix {
            Some(ref prefix) => format!("{} {}", prefix, key),
            None => key,
        };
        req_builder = req_builder.header("X-Tapis-Token", value);
    };

    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 => Err(Error::from(serde_json::Error::custom(
                "Received `text/plain` content type response that cannot be converted to `models::RespApp`",
            ))),
            ContentType::Unsupported(unknown_type) => {
                Err(Error::from(serde_json::Error::custom(format!(
                    "Received `{unknown_type}` content type response that cannot be converted to `models::RespApp`"
                ))))
            }
        }
    } else {
        let content = resp.text().await?;
        let entity: Option<GetAppLatestVersionError> = serde_json::from_str(&content).ok();
        Err(Error::ResponseError(ResponseContent {
            status,
            content,
            entity,
        }))
    }
}

/// Retrieve list of applications.  Use *listType*, *search* and *select* query parameters to limit results. Query parameter *listType* allows for filtering results based on authorization. Options for *listType* are    - *OWNED* Include only items owned by requester (Default)   - *SHARED_PUBLIC* Include only items shared publicly   - *SHARED_DIRECT* Include only items shared directly with requester. Exclude publicly shared items.   - *READ_PERM* Include only items for which requester was granter READ or MODIFY permission.   - *MINE* Include items owned or shared directly with requester. Exclude publicly shared items.   - *ALL* Include all items requester is authorized to view. Includes check for READ or MODIFY permission.  Certain Tapis services or a tenant administrator may use the query parameter *impersonationId* to be used in place of the requesting Tapis user. Tapis will use this user Id when performing authorization.
pub async fn get_apps(
    configuration: &configuration::Configuration,
    search: Option<&str>,
    list_type: Option<models::ListTypeEnum>,
    limit: Option<i32>,
    order_by: Option<&str>,
    skip: Option<i32>,
    start_after: Option<&str>,
    compute_total: Option<bool>,
    select: Option<&str>,
    show_deleted: Option<bool>,
    impersonation_id: Option<&str>,
) -> Result<models::RespApps, Error<GetAppsError>> {
    // add a prefix to parameters to efficiently prevent name collisions
    let p_query_search = search;
    let p_query_list_type = list_type;
    let p_query_limit = limit;
    let p_query_order_by = order_by;
    let p_query_skip = skip;
    let p_query_start_after = start_after;
    let p_query_compute_total = compute_total;
    let p_query_select = select;
    let p_query_show_deleted = show_deleted;
    let p_query_impersonation_id = impersonation_id;

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

    if let Some(ref param_value) = p_query_search {
        req_builder = req_builder.query(&[("search", &param_value.to_string())]);
    }
    if let Some(ref param_value) = p_query_list_type {
        req_builder = req_builder.query(&[("listType", &serde_json::to_string(param_value)?)]);
    }
    if let Some(ref param_value) = p_query_limit {
        req_builder = req_builder.query(&[("limit", &param_value.to_string())]);
    }
    if let Some(ref param_value) = p_query_order_by {
        req_builder = req_builder.query(&[("orderBy", &param_value.to_string())]);
    }
    if let Some(ref param_value) = p_query_skip {
        req_builder = req_builder.query(&[("skip", &param_value.to_string())]);
    }
    if let Some(ref param_value) = p_query_start_after {
        req_builder = req_builder.query(&[("startAfter", &param_value.to_string())]);
    }
    if let Some(ref param_value) = p_query_compute_total {
        req_builder = req_builder.query(&[("computeTotal", &param_value.to_string())]);
    }
    if let Some(ref param_value) = p_query_select {
        req_builder = req_builder.query(&[("select", &param_value.to_string())]);
    }
    if let Some(ref param_value) = p_query_show_deleted {
        req_builder = req_builder.query(&[("showDeleted", &param_value.to_string())]);
    }
    if let Some(ref param_value) = p_query_impersonation_id {
        req_builder = req_builder.query(&[("impersonationId", &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 apikey) = configuration.api_key {
        let key = apikey.key.clone();
        let value = match apikey.prefix {
            Some(ref prefix) => format!("{} {}", prefix, key),
            None => key,
        };
        req_builder = req_builder.header("X-Tapis-Token", value);
    };

    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 => Err(Error::from(serde_json::Error::custom(
                "Received `text/plain` content type response that cannot be converted to `models::RespApps`",
            ))),
            ContentType::Unsupported(unknown_type) => {
                Err(Error::from(serde_json::Error::custom(format!(
                    "Received `{unknown_type}` content type response that cannot be converted to `models::RespApps`"
                ))))
            }
        }
    } else {
        let content = resp.text().await?;
        let entity: Option<GetAppsError> = serde_json::from_str(&content).ok();
        Err(Error::ResponseError(ResponseContent {
            status,
            content,
            entity,
        }))
    }
}

/// Retrieve history of changes for a given appId.
pub async fn get_history(
    configuration: &configuration::Configuration,
    app_id: &str,
) -> Result<models::RespAppHistory, Error<GetHistoryError>> {
    // add a prefix to parameters to efficiently prevent name collisions
    let p_path_app_id = app_id;

    let uri_str = format!(
        "{}/v3/apps/{appId}/history",
        configuration.base_path,
        appId = crate::apis::urlencode(p_path_app_id)
    );
    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);

    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 apikey) = configuration.api_key {
        let key = apikey.key.clone();
        let value = match apikey.prefix {
            Some(ref prefix) => format!("{} {}", prefix, key),
            None => key,
        };
        req_builder = req_builder.header("X-Tapis-Token", value);
    };

    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 => Err(Error::from(serde_json::Error::custom(
                "Received `text/plain` content type response that cannot be converted to `models::RespAppHistory`",
            ))),
            ContentType::Unsupported(unknown_type) => {
                Err(Error::from(serde_json::Error::custom(format!(
                    "Received `{unknown_type}` content type response that cannot be converted to `models::RespAppHistory`"
                ))))
            }
        }
    } else {
        let content = resp.text().await?;
        let entity: Option<GetHistoryError> = serde_json::from_str(&content).ok();
        Err(Error::ResponseError(ResponseContent {
            status,
            content,
            entity,
        }))
    }
}

/// Check if an application is currently enabled, i.e. available for use. If the query parameter *version* is specified then both the top level attribute *enabled* and the version specific attribute *versionEnabled* are checked. Both must be set to *true* for the application to be considered *enabled*.
pub async fn is_enabled(
    configuration: &configuration::Configuration,
    app_id: &str,
    version: Option<&str>,
) -> Result<models::RespBoolean, Error<IsEnabledError>> {
    // add a prefix to parameters to efficiently prevent name collisions
    let p_path_app_id = app_id;
    let p_query_version = version;

    let uri_str = format!(
        "{}/v3/apps/{appId}/isEnabled",
        configuration.base_path,
        appId = crate::apis::urlencode(p_path_app_id)
    );
    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);

    if let Some(ref param_value) = p_query_version {
        req_builder = req_builder.query(&[("version", &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 apikey) = configuration.api_key {
        let key = apikey.key.clone();
        let value = match apikey.prefix {
            Some(ref prefix) => format!("{} {}", prefix, key),
            None => key,
        };
        req_builder = req_builder.header("X-Tapis-Token", value);
    };

    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 => Err(Error::from(serde_json::Error::custom(
                "Received `text/plain` content type response that cannot be converted to `models::RespBoolean`",
            ))),
            ContentType::Unsupported(unknown_type) => {
                Err(Error::from(serde_json::Error::custom(format!(
                    "Received `{unknown_type}` content type response that cannot be converted to `models::RespBoolean`"
                ))))
            }
        }
    } else {
        let content = resp.text().await?;
        let entity: Option<IsEnabledError> = serde_json::from_str(&content).ok();
        Err(Error::ResponseError(ResponseContent {
            status,
            content,
            entity,
        }))
    }
}

/// Lock a version of an application to prevent updates via PUT or PATCH. Requester must be owner of the app or a tenant administrator.
pub async fn lock_app(
    configuration: &configuration::Configuration,
    app_id: &str,
    app_version: &str,
) -> Result<models::RespChangeCount, Error<LockAppError>> {
    // add a prefix to parameters to efficiently prevent name collisions
    let p_path_app_id = app_id;
    let p_path_app_version = app_version;

    let uri_str = format!(
        "{}/v3/apps/{appId}/{appVersion}/lock",
        configuration.base_path,
        appId = crate::apis::urlencode(p_path_app_id),
        appVersion = crate::apis::urlencode(p_path_app_version)
    );
    let mut req_builder = configuration
        .client
        .request(reqwest::Method::POST, &uri_str);

    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 apikey) = configuration.api_key {
        let key = apikey.key.clone();
        let value = match apikey.prefix {
            Some(ref prefix) => format!("{} {}", prefix, key),
            None => key,
        };
        req_builder = req_builder.header("X-Tapis-Token", value);
    };

    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 => Err(Error::from(serde_json::Error::custom(
                "Received `text/plain` content type response that cannot be converted to `models::RespChangeCount`",
            ))),
            ContentType::Unsupported(unknown_type) => {
                Err(Error::from(serde_json::Error::custom(format!(
                    "Received `{unknown_type}` content type response that cannot be converted to `models::RespChangeCount`"
                ))))
            }
        }
    } else {
        let content = resp.text().await?;
        let entity: Option<LockAppError> = serde_json::from_str(&content).ok();
        Err(Error::ResponseError(ResponseContent {
            status,
            content,
            entity,
        }))
    }
}

/// Update selected attributes of an existing version of an application. Request body may only contain updatable attributes. Application must exist.  Attributes that may not be updated via PATCH are    - id   - owner   - enabled   - versionEnabled   - locked   - deleted  Note that the attributes owner, enabled, versionEnabled, locked and deleted may be modified using other endpoints.
pub async fn patch_app(
    configuration: &configuration::Configuration,
    app_id: &str,
    app_version: &str,
    req_patch_app: models::ReqPatchApp,
) -> Result<models::RespResourceUrl, Error<PatchAppError>> {
    // add a prefix to parameters to efficiently prevent name collisions
    let p_path_app_id = app_id;
    let p_path_app_version = app_version;
    let p_body_req_patch_app = req_patch_app;

    let uri_str = format!(
        "{}/v3/apps/{appId}/{appVersion}",
        configuration.base_path,
        appId = crate::apis::urlencode(p_path_app_id),
        appVersion = crate::apis::urlencode(p_path_app_version)
    );
    let mut req_builder = configuration
        .client
        .request(reqwest::Method::PATCH, &uri_str);

    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 apikey) = configuration.api_key {
        let key = apikey.key.clone();
        let value = match apikey.prefix {
            Some(ref prefix) => format!("{} {}", prefix, key),
            None => key,
        };
        req_builder = req_builder.header("X-Tapis-Token", value);
    };
    req_builder = req_builder.json(&p_body_req_patch_app);

    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 => Err(Error::from(serde_json::Error::custom(
                "Received `text/plain` content type response that cannot be converted to `models::RespResourceUrl`",
            ))),
            ContentType::Unsupported(unknown_type) => {
                Err(Error::from(serde_json::Error::custom(format!(
                    "Received `{unknown_type}` content type response that cannot be converted to `models::RespResourceUrl`"
                ))))
            }
        }
    } else {
        let content = resp.text().await?;
        let entity: Option<PatchAppError> = serde_json::from_str(&content).ok();
        Err(Error::ResponseError(ResponseContent {
            status,
            content,
            entity,
        }))
    }
}

/// Update all updatable attributes of an application using a request body identical to POST. Application must exist.  Note that certain attributes (such as tenant) are allowed but ignored so that the JSON result returned by a GET may be modified and used when making a PUT request to update.  The attributes that are allowed but ignored for both PUT and POST are    - tenant   - uuid   - isPublic   - sharedWithUsers   - sharedAppCtx   - deleted   - created   - updated  In addition, for a PUT operation, the following non-updatable attributes are allowed but ignored    - id   - version   - owner   - enabled   - versionEnabled   - locked  Note that the attributes owner, enabled, versionEnabled, locked and deleted may be modified using other endpoints.
pub async fn put_app(
    configuration: &configuration::Configuration,
    app_id: &str,
    app_version: &str,
    req_put_app: models::ReqPutApp,
) -> Result<models::RespResourceUrl, Error<PutAppError>> {
    // add a prefix to parameters to efficiently prevent name collisions
    let p_path_app_id = app_id;
    let p_path_app_version = app_version;
    let p_body_req_put_app = req_put_app;

    let uri_str = format!(
        "{}/v3/apps/{appId}/{appVersion}",
        configuration.base_path,
        appId = crate::apis::urlencode(p_path_app_id),
        appVersion = crate::apis::urlencode(p_path_app_version)
    );
    let mut req_builder = configuration.client.request(reqwest::Method::PUT, &uri_str);

    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 apikey) = configuration.api_key {
        let key = apikey.key.clone();
        let value = match apikey.prefix {
            Some(ref prefix) => format!("{} {}", prefix, key),
            None => key,
        };
        req_builder = req_builder.header("X-Tapis-Token", value);
    };
    req_builder = req_builder.json(&p_body_req_put_app);

    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 => Err(Error::from(serde_json::Error::custom(
                "Received `text/plain` content type response that cannot be converted to `models::RespResourceUrl`",
            ))),
            ContentType::Unsupported(unknown_type) => {
                Err(Error::from(serde_json::Error::custom(format!(
                    "Received `{unknown_type}` content type response that cannot be converted to `models::RespResourceUrl`"
                ))))
            }
        }
    } else {
        let content = resp.text().await?;
        let entity: Option<PutAppError> = serde_json::from_str(&content).ok();
        Err(Error::ResponseError(ResponseContent {
            status,
            content,
            entity,
        }))
    }
}

/// Retrieve details for applications. Use query parameters to specify search conditions. For example ?owner.eq=jdoe&enabled.eq=false Use *listType* and *select* query parameters to limit results. Query parameter *listType* allows for filtering results based on authorization. Options for *listType* are    - *OWNED* Include only items owned by requester (Default)   - *SHARED_PUBLIC* Include only items shared publicly   - *SHARED_DIRECT* Include only items shared directly with requester. Exclude publicly shared items.   - *READ_PERM* Include only items for which requester was granter READ or MODIFY permission.   - *MINE* Include items owned or shared directly with requester. Exclude publicly shared items.   - *ALL* Include all items requester is authorized to view. Includes check for READ or MODIFY permission.
pub async fn search_apps_query_parameters(
    configuration: &configuration::Configuration,
    list_type: Option<models::ListTypeEnum>,
    limit: Option<i32>,
    order_by: Option<&str>,
    skip: Option<i32>,
    start_after: Option<&str>,
    compute_total: Option<bool>,
    select: Option<&str>,
) -> Result<models::RespApps, Error<SearchAppsQueryParametersError>> {
    // add a prefix to parameters to efficiently prevent name collisions
    let p_query_list_type = list_type;
    let p_query_limit = limit;
    let p_query_order_by = order_by;
    let p_query_skip = skip;
    let p_query_start_after = start_after;
    let p_query_compute_total = compute_total;
    let p_query_select = select;

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

    if let Some(ref param_value) = p_query_list_type {
        req_builder = req_builder.query(&[("listType", &serde_json::to_string(param_value)?)]);
    }
    if let Some(ref param_value) = p_query_limit {
        req_builder = req_builder.query(&[("limit", &param_value.to_string())]);
    }
    if let Some(ref param_value) = p_query_order_by {
        req_builder = req_builder.query(&[("orderBy", &param_value.to_string())]);
    }
    if let Some(ref param_value) = p_query_skip {
        req_builder = req_builder.query(&[("skip", &param_value.to_string())]);
    }
    if let Some(ref param_value) = p_query_start_after {
        req_builder = req_builder.query(&[("startAfter", &param_value.to_string())]);
    }
    if let Some(ref param_value) = p_query_compute_total {
        req_builder = req_builder.query(&[("computeTotal", &param_value.to_string())]);
    }
    if let Some(ref param_value) = p_query_select {
        req_builder = req_builder.query(&[("select", &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 apikey) = configuration.api_key {
        let key = apikey.key.clone();
        let value = match apikey.prefix {
            Some(ref prefix) => format!("{} {}", prefix, key),
            None => key,
        };
        req_builder = req_builder.header("X-Tapis-Token", value);
    };

    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 => Err(Error::from(serde_json::Error::custom(
                "Received `text/plain` content type response that cannot be converted to `models::RespApps`",
            ))),
            ContentType::Unsupported(unknown_type) => {
                Err(Error::from(serde_json::Error::custom(format!(
                    "Received `{unknown_type}` content type response that cannot be converted to `models::RespApps`"
                ))))
            }
        }
    } else {
        let content = resp.text().await?;
        let entity: Option<SearchAppsQueryParametersError> = serde_json::from_str(&content).ok();
        Err(Error::ResponseError(ResponseContent {
            status,
            content,
            entity,
        }))
    }
}

/// Retrieve details for applications. Use request body to specify SQL-like search conditions. Use *listType* and *select* query parameters to limit results. Query parameter *listType* allows for filtering results based on authorization. Options for *listType* are    - *OWNED* Include only items owned by requester (Default)   - *SHARED_PUBLIC* Include only items shared publicly   - *SHARED_DIRECT* Include only items shared directly with requester. Exclude publicly shared items.   - *READ_PERM* Include only items for which requester was granter READ or MODIFY permission.   - *MINE* Include items owned or shared directly with requester. Exclude publicly shared items.   - *ALL* Include all items requester is authorized to view. Includes check for READ or MODIFY permission.
pub async fn search_apps_request_body(
    configuration: &configuration::Configuration,
    req_search_apps: models::ReqSearchApps,
    list_type: Option<models::ListTypeEnum>,
    limit: Option<i32>,
    order_by: Option<&str>,
    skip: Option<i32>,
    start_after: Option<&str>,
    compute_total: Option<bool>,
    select: Option<&str>,
) -> Result<models::RespApps, Error<SearchAppsRequestBodyError>> {
    // add a prefix to parameters to efficiently prevent name collisions
    let p_body_req_search_apps = req_search_apps;
    let p_query_list_type = list_type;
    let p_query_limit = limit;
    let p_query_order_by = order_by;
    let p_query_skip = skip;
    let p_query_start_after = start_after;
    let p_query_compute_total = compute_total;
    let p_query_select = select;

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

    if let Some(ref param_value) = p_query_list_type {
        req_builder = req_builder.query(&[("listType", &serde_json::to_string(param_value)?)]);
    }
    if let Some(ref param_value) = p_query_limit {
        req_builder = req_builder.query(&[("limit", &param_value.to_string())]);
    }
    if let Some(ref param_value) = p_query_order_by {
        req_builder = req_builder.query(&[("orderBy", &param_value.to_string())]);
    }
    if let Some(ref param_value) = p_query_skip {
        req_builder = req_builder.query(&[("skip", &param_value.to_string())]);
    }
    if let Some(ref param_value) = p_query_start_after {
        req_builder = req_builder.query(&[("startAfter", &param_value.to_string())]);
    }
    if let Some(ref param_value) = p_query_compute_total {
        req_builder = req_builder.query(&[("computeTotal", &param_value.to_string())]);
    }
    if let Some(ref param_value) = p_query_select {
        req_builder = req_builder.query(&[("select", &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 apikey) = configuration.api_key {
        let key = apikey.key.clone();
        let value = match apikey.prefix {
            Some(ref prefix) => format!("{} {}", prefix, key),
            None => key,
        };
        req_builder = req_builder.header("X-Tapis-Token", value);
    };
    req_builder = req_builder.json(&p_body_req_search_apps);

    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 => Err(Error::from(serde_json::Error::custom(
                "Received `text/plain` content type response that cannot be converted to `models::RespApps`",
            ))),
            ContentType::Unsupported(unknown_type) => {
                Err(Error::from(serde_json::Error::custom(format!(
                    "Received `{unknown_type}` content type response that cannot be converted to `models::RespApps`"
                ))))
            }
        }
    } else {
        let content = resp.text().await?;
        let entity: Option<SearchAppsRequestBodyError> = serde_json::from_str(&content).ok();
        Err(Error::ResponseError(ResponseContent {
            status,
            content,
            entity,
        }))
    }
}

/// Mark an application as not deleted. Application will appear in queries.
pub async fn undelete_app(
    configuration: &configuration::Configuration,
    app_id: &str,
) -> Result<models::RespChangeCount, Error<UndeleteAppError>> {
    // add a prefix to parameters to efficiently prevent name collisions
    let p_path_app_id = app_id;

    let uri_str = format!(
        "{}/v3/apps/{appId}/undelete",
        configuration.base_path,
        appId = crate::apis::urlencode(p_path_app_id)
    );
    let mut req_builder = configuration
        .client
        .request(reqwest::Method::POST, &uri_str);

    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 apikey) = configuration.api_key {
        let key = apikey.key.clone();
        let value = match apikey.prefix {
            Some(ref prefix) => format!("{} {}", prefix, key),
            None => key,
        };
        req_builder = req_builder.header("X-Tapis-Token", value);
    };

    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 => Err(Error::from(serde_json::Error::custom(
                "Received `text/plain` content type response that cannot be converted to `models::RespChangeCount`",
            ))),
            ContentType::Unsupported(unknown_type) => {
                Err(Error::from(serde_json::Error::custom(format!(
                    "Received `{unknown_type}` content type response that cannot be converted to `models::RespChangeCount`"
                ))))
            }
        }
    } else {
        let content = resp.text().await?;
        let entity: Option<UndeleteAppError> = serde_json::from_str(&content).ok();
        Err(Error::ResponseError(ResponseContent {
            status,
            content,
            entity,
        }))
    }
}

/// Unlock a version of an application to allow updates via PUT and PATCH. Requester must be owner of the app or a tenant administrator.
pub async fn unlock_app(
    configuration: &configuration::Configuration,
    app_id: &str,
    app_version: &str,
) -> Result<models::RespChangeCount, Error<UnlockAppError>> {
    // add a prefix to parameters to efficiently prevent name collisions
    let p_path_app_id = app_id;
    let p_path_app_version = app_version;

    let uri_str = format!(
        "{}/v3/apps/{appId}/{appVersion}/unlock",
        configuration.base_path,
        appId = crate::apis::urlencode(p_path_app_id),
        appVersion = crate::apis::urlencode(p_path_app_version)
    );
    let mut req_builder = configuration
        .client
        .request(reqwest::Method::POST, &uri_str);

    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 apikey) = configuration.api_key {
        let key = apikey.key.clone();
        let value = match apikey.prefix {
            Some(ref prefix) => format!("{} {}", prefix, key),
            None => key,
        };
        req_builder = req_builder.header("X-Tapis-Token", value);
    };

    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 => Err(Error::from(serde_json::Error::custom(
                "Received `text/plain` content type response that cannot be converted to `models::RespChangeCount`",
            ))),
            ContentType::Unsupported(unknown_type) => {
                Err(Error::from(serde_json::Error::custom(format!(
                    "Received `{unknown_type}` content type response that cannot be converted to `models::RespChangeCount`"
                ))))
            }
        }
    } else {
        let content = resp.text().await?;
        let entity: Option<UnlockAppError> = serde_json::from_str(&content).ok();
        Err(Error::ResponseError(ResponseContent {
            status,
            content,
            entity,
        }))
    }
}
