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

use extism_pdk::*;
use serde::{Deserialize, Serialize};
{{- if .Service.HasByteFields}}{{template "base64_bytes_module" .}}{{- end}}
{{- /* Generate struct definitions */ -}}
{{- range .Service.Structs}}
{{if .Doc}}
{{rustDocComment .Doc}}
{{else}}
{{end}}#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct {{.Name}} {
{{- range .Fields}}
{{- if .NeedsDefault}}
    #[serde(default)]
{{- end}}
{{- if .IsByteSlice}}
    #[serde(with = "base64_bytes")]
{{- end}}
    pub {{.RustName}}: {{fieldRustType .}},
{{- end}}
}
{{- end}}
{{- /* Generate request/response types */ -}}
{{- range .Service.Methods}}
{{- if .HasParams}}

#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
struct {{requestType .}} {
{{- range .Params}}
{{- if .IsByteSlice}}
    #[serde(with = "base64_bytes")]
{{- end}}
    {{.RustName}}: {{rustType .}},
{{- end}}
}
{{- end}}

#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
struct {{responseType .}} {
{{- range .Returns}}
    #[serde(default)]
{{- if .IsByteSlice}}
    #[serde(with = "base64_bytes")]
{{- end}}
    {{.RustName}}: {{rustType .}},
{{- end}}
{{- if .HasError}}
    #[serde(default)]
    error: Option<String>,
{{- end}}
}
{{- end}}

#[host_fn]
extern "ExtismHost" {
{{- range .Service.Methods}}
    fn {{exportName .}}(input: Json<{{if .HasParams}}{{requestType .}}{{else}}serde_json::Value{{end}}>) -> Json<{{responseType .}}>;
{{- end}}
}

{{- /* Generate wrapper functions */ -}}
{{range .Service.Methods}}

{{if .Doc}}{{rustDocComment .Doc}}{{else}}/// Calls the {{exportName .}} host function.{{end}}
{{- if .HasParams}}
///
/// # Arguments
{{- range .Params}}
/// * `{{.RustName}}` - {{rustType .}} parameter.
{{- end}}
{{- end}}
{{- if .HasReturns}}
///
/// # Returns
{{- if .IsOptionPattern}}
/// `Some({{(index .Returns 0).RustName}})` if found, `None` otherwise.
{{- else if eq (len .Returns) 1}}
/// The {{(index .Returns 0).RustName}} value.
{{- else}}
/// A tuple of ({{range $i, $r := .Returns}}{{if $i}}, {{end}}{{$r.RustName}}{{end}}).
{{- end}}
{{- end}}
///
/// # Errors
/// Returns an error if the host function call fails.
{{- if .IsOptionPattern}}
pub fn {{rustFunc .}}({{range $i, $p := .Params}}{{if $i}}, {{end}}{{$p.RustName}}: {{rustParamType $p}}{{end}}) -> Result<Option<{{rustType (index .Returns 0)}}>, Error> {
    let response = unsafe {
{{- if .HasParams}}
        {{exportName .}}(Json({{requestType .}} {
{{- range .Params}}
            {{.RustName}}: {{.RustName}}{{if .NeedsToOwned}}.to_owned(){{end}},
{{- end}}
        }))?
{{- else}}
        {{exportName .}}(Json(serde_json::json!({})))?
{{- end}}
    };
{{if .HasError}}
    if let Some(err) = response.0.error {
        return Err(Error::msg(err));
    }
{{end}}
    if response.0.{{(index .Returns 1).RustName}} {
        Ok(Some(response.0.{{(index .Returns 0).RustName}}))
    } else {
        Ok(None)
    }
}
{{- else}}
pub fn {{rustFunc .}}({{range $i, $p := .Params}}{{if $i}}, {{end}}{{$p.RustName}}: {{rustParamType $p}}{{end}}) -> Result<{{if eq (len .Returns) 0}}(){{else if eq (len .Returns) 1}}{{rustType (index .Returns 0)}}{{else}}({{range $i, $r := .Returns}}{{if $i}}, {{end}}{{rustType $r}}{{end}}){{end}}, Error> {
    let response = unsafe {
{{- if .HasParams}}
        {{exportName .}}(Json({{requestType .}} {
{{- range .Params}}
            {{.RustName}}: {{.RustName}}{{if .NeedsToOwned}}.to_owned(){{end}},
{{- end}}
        }))?
{{- else}}
        {{exportName .}}(Json(serde_json::json!({})))?
{{- end}}
    };
{{if .HasError}}
    if let Some(err) = response.0.error {
        return Err(Error::msg(err));
    }
{{end}}
{{- if eq (len .Returns) 0}}
    Ok(())
{{- else if eq (len .Returns) 1}}
    Ok(response.0.{{(index .Returns 0).RustName}})
{{- else}}
    Ok(({{range $i, $r := .Returns}}{{if $i}}, {{end}}response.0.{{$r.RustName}}{{end}}))
{{- end}}
}
{{- end}}
{{- end}}
