// Code generated by ndpgen. DO NOT EDIT.
//
// This file contains client wrappers for the Task host service.
// It is intended for use in Navidrome plugins built with TinyGo.
//
//go:build wasip1

package host

import (
	"encoding/json"
	"errors"

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

// QueueConfig represents the QueueConfig data structure.
// QueueConfig holds configuration for a task queue.
type QueueConfig struct {
	Concurrency int32 `json:"concurrency"`
	MaxRetries  int32 `json:"maxRetries"`
	BackoffMs   int64 `json:"backoffMs"`
	DelayMs     int64 `json:"delayMs"`
	RetentionMs int64 `json:"retentionMs"`
}

// TaskInfo represents the TaskInfo data structure.
// TaskInfo holds the current state of a task.
type TaskInfo struct {
	Status  string `json:"status"`
	Message string `json:"message"`
	Attempt int32  `json:"attempt"`
}

// task_createqueue is the host function provided by Navidrome.
//
//go:wasmimport extism:host/user task_createqueue
func task_createqueue(uint64) uint64

// task_enqueue is the host function provided by Navidrome.
//
//go:wasmimport extism:host/user task_enqueue
func task_enqueue(uint64) uint64

// task_get is the host function provided by Navidrome.
//
//go:wasmimport extism:host/user task_get
func task_get(uint64) uint64

// task_cancel is the host function provided by Navidrome.
//
//go:wasmimport extism:host/user task_cancel
func task_cancel(uint64) uint64

// task_clearqueue is the host function provided by Navidrome.
//
//go:wasmimport extism:host/user task_clearqueue
func task_clearqueue(uint64) uint64

type taskCreateQueueRequest struct {
	Name   string      `json:"name"`
	Config QueueConfig `json:"config"`
}

type taskEnqueueRequest struct {
	QueueName string `json:"queueName"`
	Payload   []byte `json:"payload"`
}

type taskEnqueueResponse struct {
	Result string `json:"result,omitempty"`
	Error  string `json:"error,omitempty"`
}

type taskGetRequest struct {
	TaskID string `json:"taskId"`
}

type taskGetResponse struct {
	Result *TaskInfo `json:"result,omitempty"`
	Error  string    `json:"error,omitempty"`
}

type taskCancelRequest struct {
	TaskID string `json:"taskId"`
}

type taskClearQueueRequest struct {
	QueueName string `json:"queueName"`
}

type taskClearQueueResponse struct {
	Result int64  `json:"result,omitempty"`
	Error  string `json:"error,omitempty"`
}

// TaskCreateQueue calls the task_createqueue host function.
// CreateQueue creates a named task queue with the given configuration.
// Zero-value fields in config use sensible defaults.
// If a queue with the same name already exists, returns an error.
// On startup, this also recovers any stale "running" tasks from a previous crash.
func TaskCreateQueue(name string, config QueueConfig) error {
	// Marshal request to JSON
	req := taskCreateQueueRequest{
		Name:   name,
		Config: config,
	}
	reqBytes, err := json.Marshal(req)
	if err != nil {
		return err
	}
	reqMem := pdk.AllocateBytes(reqBytes)
	defer reqMem.Free()

	// Call the host function
	responsePtr := task_createqueue(reqMem.Offset())

	// Read the response from memory
	responseMem := pdk.FindMemory(responsePtr)
	responseBytes := responseMem.ReadBytes()

	// 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
}

// TaskEnqueue calls the task_enqueue host function.
// Enqueue adds a task to the named queue. Returns the task ID.
// payload is opaque bytes passed back to the plugin on execution.
func TaskEnqueue(queueName string, payload []byte) (string, error) {
	// Marshal request to JSON
	req := taskEnqueueRequest{
		QueueName: queueName,
		Payload:   payload,
	}
	reqBytes, err := json.Marshal(req)
	if err != nil {
		return "", err
	}
	reqMem := pdk.AllocateBytes(reqBytes)
	defer reqMem.Free()

	// Call the host function
	responsePtr := task_enqueue(reqMem.Offset())

	// Read the response from memory
	responseMem := pdk.FindMemory(responsePtr)
	responseBytes := responseMem.ReadBytes()

	// Parse the response
	var response taskEnqueueResponse
	if err := json.Unmarshal(responseBytes, &response); err != nil {
		return "", err
	}

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

	return response.Result, nil
}

// TaskGet calls the task_get host function.
// Get returns the current state of a task including its status,
// message, and attempt count.
func TaskGet(taskID string) (*TaskInfo, error) {
	// Marshal request to JSON
	req := taskGetRequest{
		TaskID: taskID,
	}
	reqBytes, err := json.Marshal(req)
	if err != nil {
		return nil, err
	}
	reqMem := pdk.AllocateBytes(reqBytes)
	defer reqMem.Free()

	// Call the host function
	responsePtr := task_get(reqMem.Offset())

	// Read the response from memory
	responseMem := pdk.FindMemory(responsePtr)
	responseBytes := responseMem.ReadBytes()

	// Parse the response
	var response taskGetResponse
	if err := json.Unmarshal(responseBytes, &response); err != nil {
		return nil, err
	}

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

	return response.Result, nil
}

// TaskCancel calls the task_cancel host function.
// Cancel cancels a pending task. Returns error if already
// running, completed, or failed.
func TaskCancel(taskID string) error {
	// Marshal request to JSON
	req := taskCancelRequest{
		TaskID: taskID,
	}
	reqBytes, err := json.Marshal(req)
	if err != nil {
		return err
	}
	reqMem := pdk.AllocateBytes(reqBytes)
	defer reqMem.Free()

	// Call the host function
	responsePtr := task_cancel(reqMem.Offset())

	// Read the response from memory
	responseMem := pdk.FindMemory(responsePtr)
	responseBytes := responseMem.ReadBytes()

	// 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
}

// TaskClearQueue calls the task_clearqueue host function.
// ClearQueue removes all pending tasks from the named queue.
// Running tasks are not affected. Returns the number of tasks removed.
func TaskClearQueue(queueName string) (int64, error) {
	// Marshal request to JSON
	req := taskClearQueueRequest{
		QueueName: queueName,
	}
	reqBytes, err := json.Marshal(req)
	if err != nil {
		return 0, err
	}
	reqMem := pdk.AllocateBytes(reqBytes)
	defer reqMem.Free()

	// Call the host function
	responsePtr := task_clearqueue(reqMem.Offset())

	// Read the response from memory
	responseMem := pdk.FindMemory(responsePtr)
	responseBytes := responseMem.ReadBytes()

	// Parse the response
	var response taskClearQueueResponse
	if err := json.Unmarshal(responseBytes, &response); err != nil {
		return 0, err
	}

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

	return response.Result, nil
}
