// Code generated by ndpgen. DO NOT EDIT.
//
// This file contains client wrappers for the Comprehensive host service.
// It is intended for use in Navidrome plugins built with extism-pdk.

use extism_pdk::*;
use serde::{Deserialize, Serialize};
use base64::Engine as _;
use base64::engine::general_purpose::STANDARD as BASE64;

mod base64_bytes {
    use serde::{self, Deserialize, Deserializer, Serializer};
    use base64::Engine as _;
    use base64::engine::general_purpose::STANDARD as BASE64;

    pub fn serialize<S>(bytes: &Vec<u8>, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        serializer.serialize_str(&BASE64.encode(bytes))
    }

    pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
    where
        D: Deserializer<'de>,
    {
        let s = String::deserialize(deserializer)?;
        BASE64.decode(&s).map_err(serde::de::Error::custom)
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct User2 {
    pub id: String,
    pub name: String,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Filter2 {
    pub active: bool,
}

#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
struct ComprehensiveSimpleParamsRequest {
    name: String,
    count: i32,
}

#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
struct ComprehensiveSimpleParamsResponse {
    #[serde(default)]
    result: String,
    #[serde(default)]
    error: Option<String>,
}

#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
struct ComprehensiveStructParamRequest {
    user: User2,
}

#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
struct ComprehensiveStructParamResponse {
    #[serde(default)]
    error: Option<String>,
}

#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
struct ComprehensiveMixedParamsRequest {
    id: String,
    filter: Filter2,
}

#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
struct ComprehensiveMixedParamsResponse {
    #[serde(default)]
    result: i32,
    #[serde(default)]
    error: Option<String>,
}

#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
struct ComprehensiveNoErrorRequest {
    name: String,
}

#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
struct ComprehensiveNoErrorResponse {
    #[serde(default)]
    result: String,
    #[serde(default)]
    error: Option<String>,
}

#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
struct ComprehensiveNoParamsResponse {
    #[serde(default)]
    error: Option<String>,
}

#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
struct ComprehensiveNoParamsNoReturnsResponse {
    #[serde(default)]
    error: Option<String>,
}

#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
struct ComprehensivePointerParamsRequest {
    id: Option<String>,
    user: Option<User2>,
}

#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
struct ComprehensivePointerParamsResponse {
    #[serde(default)]
    result: Option<User2>,
    #[serde(default)]
    error: Option<String>,
}

#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
struct ComprehensiveMapParamsRequest {
    data: std::collections::HashMap<String, serde_json::Value>,
}

#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
struct ComprehensiveMapParamsResponse {
    #[serde(default)]
    result: serde_json::Value,
    #[serde(default)]
    error: Option<String>,
}

#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
struct ComprehensiveMultipleReturnsRequest {
    query: String,
}

#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
struct ComprehensiveMultipleReturnsResponse {
    #[serde(default)]
    results: Vec<User2>,
    #[serde(default)]
    total: i32,
    #[serde(default)]
    error: Option<String>,
}

#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
struct ComprehensiveByteSliceRequest {
    #[serde(with = "base64_bytes")]
    data: Vec<u8>,
}

#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
struct ComprehensiveByteSliceResponse {
    #[serde(default)]
    #[serde(with = "base64_bytes")]
    result: Vec<u8>,
    #[serde(default)]
    error: Option<String>,
}

#[host_fn]
extern "ExtismHost" {
    fn comprehensive_simpleparams(input: Json<ComprehensiveSimpleParamsRequest>) -> Json<ComprehensiveSimpleParamsResponse>;
    fn comprehensive_structparam(input: Json<ComprehensiveStructParamRequest>) -> Json<ComprehensiveStructParamResponse>;
    fn comprehensive_mixedparams(input: Json<ComprehensiveMixedParamsRequest>) -> Json<ComprehensiveMixedParamsResponse>;
    fn comprehensive_noerror(input: Json<ComprehensiveNoErrorRequest>) -> Json<ComprehensiveNoErrorResponse>;
    fn comprehensive_noparams(input: Json<serde_json::Value>) -> Json<ComprehensiveNoParamsResponse>;
    fn comprehensive_noparamsnoreturns(input: Json<serde_json::Value>) -> Json<ComprehensiveNoParamsNoReturnsResponse>;
    fn comprehensive_pointerparams(input: Json<ComprehensivePointerParamsRequest>) -> Json<ComprehensivePointerParamsResponse>;
    fn comprehensive_mapparams(input: Json<ComprehensiveMapParamsRequest>) -> Json<ComprehensiveMapParamsResponse>;
    fn comprehensive_multiplereturns(input: Json<ComprehensiveMultipleReturnsRequest>) -> Json<ComprehensiveMultipleReturnsResponse>;
    fn comprehensive_byteslice(input: Json<ComprehensiveByteSliceRequest>) -> Json<ComprehensiveByteSliceResponse>;
}

/// Calls the comprehensive_simpleparams host function.
///
/// # Arguments
/// * `name` - String parameter.
/// * `count` - i32 parameter.
///
/// # Returns
/// The result value.
///
/// # Errors
/// Returns an error if the host function call fails.
pub fn simple_params(name: &str, count: i32) -> Result<String, Error> {
    let response = unsafe {
        comprehensive_simpleparams(Json(ComprehensiveSimpleParamsRequest {
            name: name.to_owned(),
            count: count,
        }))?
    };

    if let Some(err) = response.0.error {
        return Err(Error::msg(err));
    }

    Ok(response.0.result)
}

/// Calls the comprehensive_structparam host function.
///
/// # Arguments
/// * `user` - User2 parameter.
///
/// # Errors
/// Returns an error if the host function call fails.
pub fn struct_param(user: User2) -> Result<(), Error> {
    let response = unsafe {
        comprehensive_structparam(Json(ComprehensiveStructParamRequest {
            user: user,
        }))?
    };

    if let Some(err) = response.0.error {
        return Err(Error::msg(err));
    }

    Ok(())
}

/// Calls the comprehensive_mixedparams host function.
///
/// # Arguments
/// * `id` - String parameter.
/// * `filter` - Filter2 parameter.
///
/// # Returns
/// The result value.
///
/// # Errors
/// Returns an error if the host function call fails.
pub fn mixed_params(id: &str, filter: Filter2) -> Result<i32, Error> {
    let response = unsafe {
        comprehensive_mixedparams(Json(ComprehensiveMixedParamsRequest {
            id: id.to_owned(),
            filter: filter,
        }))?
    };

    if let Some(err) = response.0.error {
        return Err(Error::msg(err));
    }

    Ok(response.0.result)
}

/// Calls the comprehensive_noerror host function.
///
/// # Arguments
/// * `name` - String parameter.
///
/// # Returns
/// The result value.
///
/// # Errors
/// Returns an error if the host function call fails.
pub fn no_error(name: &str) -> Result<String, Error> {
    let response = unsafe {
        comprehensive_noerror(Json(ComprehensiveNoErrorRequest {
            name: name.to_owned(),
        }))?
    };

    if let Some(err) = response.0.error {
        return Err(Error::msg(err));
    }

    Ok(response.0.result)
}

/// Calls the comprehensive_noparams host function.
///
/// # Errors
/// Returns an error if the host function call fails.
pub fn no_params() -> Result<(), Error> {
    let response = unsafe {
        comprehensive_noparams(Json(serde_json::json!({})))?
    };

    if let Some(err) = response.0.error {
        return Err(Error::msg(err));
    }

    Ok(())
}

/// Calls the comprehensive_noparamsnoreturns host function.
///
/// # Errors
/// Returns an error if the host function call fails.
pub fn no_params_no_returns() -> Result<(), Error> {
    let response = unsafe {
        comprehensive_noparamsnoreturns(Json(serde_json::json!({})))?
    };

    if let Some(err) = response.0.error {
        return Err(Error::msg(err));
    }

    Ok(())
}

/// Calls the comprehensive_pointerparams host function.
///
/// # Arguments
/// * `id` - Option<String> parameter.
/// * `user` - Option<User2> parameter.
///
/// # Returns
/// The result value.
///
/// # Errors
/// Returns an error if the host function call fails.
pub fn pointer_params(id: Option<String>, user: Option<User2>) -> Result<Option<User2>, Error> {
    let response = unsafe {
        comprehensive_pointerparams(Json(ComprehensivePointerParamsRequest {
            id: id,
            user: user,
        }))?
    };

    if let Some(err) = response.0.error {
        return Err(Error::msg(err));
    }

    Ok(response.0.result)
}

/// Calls the comprehensive_mapparams host function.
///
/// # Arguments
/// * `data` - std::collections::HashMap<String, serde_json::Value> parameter.
///
/// # Returns
/// The result value.
///
/// # Errors
/// Returns an error if the host function call fails.
pub fn map_params(data: std::collections::HashMap<String, serde_json::Value>) -> Result<serde_json::Value, Error> {
    let response = unsafe {
        comprehensive_mapparams(Json(ComprehensiveMapParamsRequest {
            data: data,
        }))?
    };

    if let Some(err) = response.0.error {
        return Err(Error::msg(err));
    }

    Ok(response.0.result)
}

/// Calls the comprehensive_multiplereturns host function.
///
/// # Arguments
/// * `query` - String parameter.
///
/// # Returns
/// A tuple of (results, total).
///
/// # Errors
/// Returns an error if the host function call fails.
pub fn multiple_returns(query: &str) -> Result<(Vec<User2>, i32), Error> {
    let response = unsafe {
        comprehensive_multiplereturns(Json(ComprehensiveMultipleReturnsRequest {
            query: query.to_owned(),
        }))?
    };

    if let Some(err) = response.0.error {
        return Err(Error::msg(err));
    }

    Ok((response.0.results, response.0.total))
}

/// Calls the comprehensive_byteslice host function.
///
/// # Arguments
/// * `data` - Vec<u8> parameter.
///
/// # Returns
/// The result value.
///
/// # Errors
/// Returns an error if the host function call fails.
pub fn byte_slice(data: Vec<u8>) -> Result<Vec<u8>, Error> {
    let response = unsafe {
        comprehensive_byteslice(Json(ComprehensiveByteSliceRequest {
            data: data,
        }))?
    };

    if let Some(err) = response.0.error {
        return Err(Error::msg(err));
    }

    Ok(response.0.result)
}
