// 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 TinyGo.
//
//go:build wasip1

package {{.Package}}

import (
	"encoding/json"
{{- if .Service.HasErrors}}
	"errors"
{{- end}}

	"github.com/navidrome/navidrome/plugins/pdk/go/pdk"
)

{{- /* Generate struct definitions */ -}}
{{- range .Service.Structs}}

// {{.Name}} represents the {{.Name}} data structure.
{{- if .Doc}}
{{formatDoc .Doc}}
{{- end}}
type {{.Name}} struct {
{{- range .Fields}}
	{{.Name}} {{.Type}} `json:"{{.JSONTag}}"`
{{- end}}
}
{{- end}}

{{- /* Generate wasmimport declarations for each method */ -}}
{{range .Service.Methods}}

// {{exportName .}} is the host function provided by Navidrome.
//
//go:wasmimport extism:host/user {{exportName .}}
func {{exportName .}}(uint64) uint64
{{- end}}

{{- /* Generate request/response types for all methods (private) */ -}}
{{range .Service.Methods}}
{{- if .HasParams}}

type {{requestType .}} struct {
{{- range .Params}}
	{{title .Name}} {{.Type}} `json:"{{.JSONName}}"`
{{- end}}
}
{{- end}}
{{- if not .IsErrorOnly}}

type {{responseType .}} struct {
{{- range .Returns}}
	{{title .Name}} {{.Type}} `json:"{{.JSONName}},omitempty"`
{{- end}}
{{- if .HasError}}
	Error string `json:"error,omitempty"`
{{- end}}
}
{{- end}}
{{- end}}

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

// {{$.Service.Name}}{{.Name}} calls the {{exportName .}} host function.
{{- if .Doc}}
{{formatDoc .Doc}}
{{- end}}
func {{$.Service.Name}}{{.Name}}({{range $i, $p := .Params}}{{if $i}}, {{end}}{{$p.Name}} {{$p.Type}}{{end}}) {{.ReturnSignature}} {
{{- if .HasParams}}
	// Marshal request to JSON
	req := {{requestType .}}{
{{- range .Params}}
		{{title .Name}}: {{.Name}},
{{- end}}
	}
	reqBytes, err := json.Marshal(req)
	if err != nil {
		return {{if .HasReturns}}{{.ZeroValues}}{{end}}{{if and .HasReturns .HasError}}, {{end}}{{if .HasError}}err{{end}}
	}
	reqMem := pdk.AllocateBytes(reqBytes)
	defer reqMem.Free()
{{- else}}
	// No parameters - allocate empty JSON object
	reqMem := pdk.AllocateBytes([]byte("{}"))
	defer reqMem.Free()
{{- end}}

	// Call the host function
	responsePtr := {{exportName .}}(reqMem.Offset())

	// Read the response from memory
	responseMem := pdk.FindMemory(responsePtr)
	responseBytes := responseMem.ReadBytes()
{{- if .IsErrorOnly}}

	// Parse error-only response
	var response struct {
		Error string `json:"error,omitempty"`
	}
	if err := json.Unmarshal(responseBytes, &response); err != nil {
		return err
	}
	if response.Error != "" {
		return errors.New(response.Error)
	}
	return nil
{{- else}}

	// Parse the response
	var response {{responseType .}}
	if err := json.Unmarshal(responseBytes, &response); err != nil {
		return {{if .HasReturns}}{{.ZeroValues}}{{end}}{{if and .HasReturns .HasError}}, {{end}}{{if .HasError}}err{{end}}
	}
{{- if .HasError}}

	// Convert Error field to Go error
	if response.Error != "" {
		return {{if .HasReturns}}{{.ZeroValues}}, {{end}}errors.New(response.Error)
	}
{{- end}}

	return {{range $i, $r := .Returns}}{{if $i}}, {{end}}response.{{title $r.Name}}{{end}}{{if and .HasReturns .HasError}}, {{end}}{{if .HasError}}nil{{end}}
{{- end}}
}
{{- end}}
