// Code generated by ndpgen. DO NOT EDIT.
//
// This file contains export wrappers for the {{.Capability.Interface}} capability.
// It is intended for use in Navidrome plugins built with TinyGo.
//
//go:build wasip1

package {{.Package}}

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

{{- /* Generate type alias definitions */ -}}
{{- range .Capability.TypeAliases}}

{{- if .Doc}}
{{formatDoc .Doc}}
{{- end}}
type {{.Name}} {{.Type}}
{{- end}}

{{- /* Generate const definitions */ -}}
{{- range .Capability.Consts}}
{{- if .Values}}

const (
{{- $type := .Type}}
{{- range $i, $v := .Values}}
{{- if $v.Doc}}
{{formatDoc $v.Doc | indent 1}}
{{- end}}
{{- if $type}}
	{{$v.Name}} {{$type}} = {{$v.Value}}
{{- else}}
	{{$v.Name}} = {{$v.Value}}
{{- end}}
{{- end}}
)
{{- end}}
{{- end}}

{{- /* Generate Error() methods for string type aliases with const values (implements error interface) */ -}}
{{- $consts := .Capability.Consts}}
{{- range .Capability.TypeAliases}}
{{- if eq .Type "string"}}
{{- $typeName := .Name}}
{{- range $consts}}
{{- if eq .Type $typeName}}

// Error implements the error interface for {{$typeName}}.
func (e {{$typeName}}) Error() string { return string(e) }
{{- end}}
{{- end}}
{{- end}}
{{- end}}

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

{{- if .Doc}}
{{formatDoc .Doc}}
{{- else}}
// {{.Name}} represents the {{.Name}} data structure.
{{- end}}
type {{.Name}} struct {
{{- range .Fields}}
{{- if .Doc}}
{{formatDoc .Doc | indent 1}}
{{- end}}
	{{.Name}} {{.Type}} `json:"{{.JSONTag}}{{if .OmitEmpty}},omitempty{{end}}"`
{{- end}}
}
{{- end}}

{{- /* Generate main interface based on required flag */ -}}
{{if .Capability.Required}}

// {{agentName .Capability}} requires all methods to be implemented.
{{- if .Capability.Doc}}
{{formatDoc .Capability.Doc}}
{{- end}}
type {{agentName .Capability}} interface {
{{- range .Capability.Methods}}
	// {{.Name}}{{if .Doc}} - {{.Doc}}{{end}}
	{{- if and .HasInput .HasOutput}}
	{{.Name}}({{.Input.Type}}) ({{.Output.Type}}, error)
	{{- else if .HasInput}}
	{{.Name}}({{.Input.Type}}) error
	{{- else if .HasOutput}}
	{{.Name}}() ({{.Output.Type}}, error)
	{{- else}}
	{{.Name}}() error
	{{- end}}
{{- end}}
}
{{- else}}

// {{agentName .Capability}} is the marker interface for {{.Package}} plugins.
// Implement one or more of the provider interfaces below.
{{- if .Capability.Doc}}
{{formatDoc .Capability.Doc}}
{{- end}}
type {{agentName .Capability}} interface{}
{{- end}}

{{- /* Generate optional provider interfaces for non-required capabilities */ -}}
{{- if not .Capability.Required}}
{{- range .Capability.Methods}}

// {{providerInterface .}} provides the {{.Name}} function.
type {{providerInterface .}} interface {
	{{- if and .HasInput .HasOutput}}
	{{.Name}}({{.Input.Type}}) ({{.Output.Type}}, error)
	{{- else if .HasInput}}
	{{.Name}}({{.Input.Type}}) error
	{{- else if .HasOutput}}
	{{.Name}}() ({{.Output.Type}}, error)
	{{- else}}
	{{.Name}}() error
	{{- end}}
}
{{- end}}
{{- end}}

{{- /* Generate implementation function holders */ -}}

// Internal implementation holders
var (
{{- range .Capability.Methods}}
	{{- if and .HasInput .HasOutput}}
	{{implVar .}} func({{.Input.Type}}) ({{.Output.Type}}, error)
	{{- else if .HasInput}}
	{{implVar .}} func({{.Input.Type}}) error
	{{- else if .HasOutput}}
	{{implVar .}} func() ({{.Output.Type}}, error)
	{{- else}}
	{{implVar .}} func() error
	{{- end}}
{{- end}}
)

// Register registers a {{.Package}} implementation.
{{- if .Capability.Required}}
// All methods are required.
func Register(impl {{agentName .Capability}}) {
{{- range .Capability.Methods}}
	{{implVar .}} = impl.{{.Name}}
{{- end}}
}
{{- else}}
// The implementation is checked for optional provider interfaces.
func Register(impl {{agentName .Capability}}) {
{{- range .Capability.Methods}}
	if p, ok := impl.({{providerInterface .}}); ok {
		{{implVar .}} = p.{{.Name}}
	}
{{- end}}
}
{{- end}}

// NotImplementedCode is the standard return code for unimplemented functions.
// The host recognizes this and skips the plugin gracefully.
const NotImplementedCode int32 = -2

{{- /* Generate export wrappers */ -}}
{{range .Capability.Methods}}

//go:wasmexport {{.ExportName}}
func {{exportFunc .}}() int32 {
	if {{implVar .}} == nil {
		// Return standard code - host will skip this plugin gracefully
		return NotImplementedCode
	}
{{- if .HasInput}}

	var input {{.Input.Type}}
	if err := pdk.InputJSON(&input); err != nil {
		pdk.SetError(err)
		return -1
	}
{{- end}}
{{- if and .HasInput .HasOutput}}

	output, err := {{implVar .}}(input)
	if err != nil {
		pdk.SetError(err)
		return -1
	}

	if err := pdk.OutputJSON(output); err != nil {
		pdk.SetError(err)
		return -1
	}
{{- else if .HasInput}}

	if err := {{implVar .}}(input); err != nil {
		pdk.SetError(err)
		return -1
	}
{{- else if .HasOutput}}

	output, err := {{implVar .}}()
	if err != nil {
		pdk.SetError(err)
		return -1
	}

	if err := pdk.OutputJSON(output); err != nil {
		pdk.SetError(err)
		return -1
	}
{{- else}}

	if err := {{implVar .}}(); err != nil {
		pdk.SetError(err)
		return -1
	}
{{- end}}

	return 0
}
{{- end}}
