// @generated by flare-im-core-sdk-xtask
// Source: bindings/contract/dispatch.json

// Do not edit by hand.
#![allow(clippy::too_many_lines, unused_imports)]

use crate::dispatch_support::*;
use crate::{BindingResponse, binding_operation_not_supported};
use flare_im_core_sdk::Result;
use flare_im_core_sdk::client::IMClient;
use flare_im_core_sdk::client::api::CapabilityApi;
use flare_im_core_sdk::serde_json::{self, Value};
use std::sync::Arc;

pub const CAPABILITY_DISPATCH_OPERATIONS: &[&str] = &[
    "capability_list",
    "capability_list_user",
    "capability_dispatch",
    "capability_grant",
    "capability_revoke",
];

pub fn is_capability_operation(operation: &str) -> bool {
    CAPABILITY_DISPATCH_OPERATIONS.contains(&operation)
}

pub async fn dispatch_capability(
    api: &Arc<CapabilityApi>,
    _client: &IMClient,
    operation: &str,
    params: Value,
) -> Result<BindingResponse> {
    match operation {
        "capability_list" => json(api.list_capabilities().await?),
        "capability_list_user" => {
            let tenant_id_o = optional_string(&params, "tenantId");
            let user_id_o = optional_string(&params, "userId");
            json(
                api.list_user_capabilities(tenant_id_o.as_deref(), user_id_o.as_deref())
                    .await?,
            )
        }
        "capability_dispatch" => {
            let capability_id_s = json_string(&params, "capabilityId")?;
            let conversation_id_o = optional_string(&params, "conversationId");
            let tenant_id_o = optional_string(&params, "tenantId");
            let user_id_o = optional_string(&params, "userId");
            json(
                api.dispatch(
                    &capability_id_s,
                    params
                        .get("payload")
                        .cloned()
                        .unwrap_or(serde_json::Value::Null),
                    conversation_id_o.as_deref(),
                    tenant_id_o.as_deref(),
                    user_id_o.as_deref(),
                )
                .await?,
            )
        }
        "capability_grant" => {
            let tenant_id_s = json_string(&params, "tenantId")?;
            let user_id_s = json_string(&params, "userId")?;
            let capability_id_s = json_string(&params, "capabilityId")?;
            let expires_at_rfc3339_o = optional_string(&params, "expiresAtRfc3339");
            let plan_code_o = optional_string(&params, "planCode");
            let source_o = optional_string(&params, "source");
            api.grant_user_capability(
                &tenant_id_s,
                &user_id_s,
                &capability_id_s,
                expires_at_rfc3339_o.as_deref(),
                plan_code_o.as_deref(),
                source_o.as_deref(),
            )
            .await?;
            Ok(BindingResponse::unit())
        }
        "capability_revoke" => {
            let tenant_id_s = json_string(&params, "tenantId")?;
            let user_id_s = json_string(&params, "userId")?;
            let capability_id_s = json_string(&params, "capabilityId")?;
            api.revoke_user_capability(&tenant_id_s, &user_id_s, &capability_id_s)
                .await?;
            Ok(BindingResponse::unit())
        }
        _ => Err(binding_operation_not_supported(operation)),
    }
}

pub async fn dispatch_capability_json(
    api: &Arc<CapabilityApi>,
    client: &IMClient,
    operation: &str,
    params_json: &str,
) -> Result<BindingResponse> {
    let params = dispatch_params_from_json(params_json)?;
    dispatch_capability(api, client, operation, params).await
}
