// Code generated by ndpgen. DO NOT EDIT.

package host

import (
	"context"
	"encoding/json"

	extism "github.com/extism/go-sdk"
)

// TaskCreateQueueRequest is the request type for Task.CreateQueue.
type TaskCreateQueueRequest struct {
	Name   string      `json:"name"`
	Config QueueConfig `json:"config"`
}

// TaskCreateQueueResponse is the response type for Task.CreateQueue.
type TaskCreateQueueResponse struct {
	Error string `json:"error,omitempty"`
}

// TaskEnqueueRequest is the request type for Task.Enqueue.
type TaskEnqueueRequest struct {
	QueueName string `json:"queueName"`
	Payload   []byte `json:"payload"`
}

// TaskEnqueueResponse is the response type for Task.Enqueue.
type TaskEnqueueResponse struct {
	Result string `json:"result,omitempty"`
	Error  string `json:"error,omitempty"`
}

// TaskGetRequest is the request type for Task.Get.
type TaskGetRequest struct {
	TaskID string `json:"taskId"`
}

// TaskGetResponse is the response type for Task.Get.
type TaskGetResponse struct {
	Result *TaskInfo `json:"result,omitempty"`
	Error  string    `json:"error,omitempty"`
}

// TaskCancelRequest is the request type for Task.Cancel.
type TaskCancelRequest struct {
	TaskID string `json:"taskId"`
}

// TaskCancelResponse is the response type for Task.Cancel.
type TaskCancelResponse struct {
	Error string `json:"error,omitempty"`
}

// TaskClearQueueRequest is the request type for Task.ClearQueue.
type TaskClearQueueRequest struct {
	QueueName string `json:"queueName"`
}

// TaskClearQueueResponse is the response type for Task.ClearQueue.
type TaskClearQueueResponse struct {
	Result int64  `json:"result,omitempty"`
	Error  string `json:"error,omitempty"`
}

// RegisterTaskHostFunctions registers Task service host functions.
// The returned host functions should be added to the plugin's configuration.
func RegisterTaskHostFunctions(service TaskService) []extism.HostFunction {
	return []extism.HostFunction{
		newTaskCreateQueueHostFunction(service),
		newTaskEnqueueHostFunction(service),
		newTaskGetHostFunction(service),
		newTaskCancelHostFunction(service),
		newTaskClearQueueHostFunction(service),
	}
}

func newTaskCreateQueueHostFunction(service TaskService) extism.HostFunction {
	return extism.NewHostFunctionWithStack(
		"task_createqueue",
		func(ctx context.Context, p *extism.CurrentPlugin, stack []uint64) {
			// Read JSON request from plugin memory
			reqBytes, err := p.ReadBytes(stack[0])
			if err != nil {
				taskWriteError(p, stack, err)
				return
			}
			var req TaskCreateQueueRequest
			if err := json.Unmarshal(reqBytes, &req); err != nil {
				taskWriteError(p, stack, err)
				return
			}

			// Call the service method
			if svcErr := service.CreateQueue(ctx, req.Name, req.Config); svcErr != nil {
				taskWriteError(p, stack, svcErr)
				return
			}

			// Write JSON response to plugin memory
			resp := TaskCreateQueueResponse{}
			taskWriteResponse(p, stack, resp)
		},
		[]extism.ValueType{extism.ValueTypePTR},
		[]extism.ValueType{extism.ValueTypePTR},
	)
}

func newTaskEnqueueHostFunction(service TaskService) extism.HostFunction {
	return extism.NewHostFunctionWithStack(
		"task_enqueue",
		func(ctx context.Context, p *extism.CurrentPlugin, stack []uint64) {
			// Read JSON request from plugin memory
			reqBytes, err := p.ReadBytes(stack[0])
			if err != nil {
				taskWriteError(p, stack, err)
				return
			}
			var req TaskEnqueueRequest
			if err := json.Unmarshal(reqBytes, &req); err != nil {
				taskWriteError(p, stack, err)
				return
			}

			// Call the service method
			result, svcErr := service.Enqueue(ctx, req.QueueName, req.Payload)
			if svcErr != nil {
				taskWriteError(p, stack, svcErr)
				return
			}

			// Write JSON response to plugin memory
			resp := TaskEnqueueResponse{
				Result: result,
			}
			taskWriteResponse(p, stack, resp)
		},
		[]extism.ValueType{extism.ValueTypePTR},
		[]extism.ValueType{extism.ValueTypePTR},
	)
}

func newTaskGetHostFunction(service TaskService) extism.HostFunction {
	return extism.NewHostFunctionWithStack(
		"task_get",
		func(ctx context.Context, p *extism.CurrentPlugin, stack []uint64) {
			// Read JSON request from plugin memory
			reqBytes, err := p.ReadBytes(stack[0])
			if err != nil {
				taskWriteError(p, stack, err)
				return
			}
			var req TaskGetRequest
			if err := json.Unmarshal(reqBytes, &req); err != nil {
				taskWriteError(p, stack, err)
				return
			}

			// Call the service method
			result, svcErr := service.Get(ctx, req.TaskID)
			if svcErr != nil {
				taskWriteError(p, stack, svcErr)
				return
			}

			// Write JSON response to plugin memory
			resp := TaskGetResponse{
				Result: result,
			}
			taskWriteResponse(p, stack, resp)
		},
		[]extism.ValueType{extism.ValueTypePTR},
		[]extism.ValueType{extism.ValueTypePTR},
	)
}

func newTaskCancelHostFunction(service TaskService) extism.HostFunction {
	return extism.NewHostFunctionWithStack(
		"task_cancel",
		func(ctx context.Context, p *extism.CurrentPlugin, stack []uint64) {
			// Read JSON request from plugin memory
			reqBytes, err := p.ReadBytes(stack[0])
			if err != nil {
				taskWriteError(p, stack, err)
				return
			}
			var req TaskCancelRequest
			if err := json.Unmarshal(reqBytes, &req); err != nil {
				taskWriteError(p, stack, err)
				return
			}

			// Call the service method
			if svcErr := service.Cancel(ctx, req.TaskID); svcErr != nil {
				taskWriteError(p, stack, svcErr)
				return
			}

			// Write JSON response to plugin memory
			resp := TaskCancelResponse{}
			taskWriteResponse(p, stack, resp)
		},
		[]extism.ValueType{extism.ValueTypePTR},
		[]extism.ValueType{extism.ValueTypePTR},
	)
}

func newTaskClearQueueHostFunction(service TaskService) extism.HostFunction {
	return extism.NewHostFunctionWithStack(
		"task_clearqueue",
		func(ctx context.Context, p *extism.CurrentPlugin, stack []uint64) {
			// Read JSON request from plugin memory
			reqBytes, err := p.ReadBytes(stack[0])
			if err != nil {
				taskWriteError(p, stack, err)
				return
			}
			var req TaskClearQueueRequest
			if err := json.Unmarshal(reqBytes, &req); err != nil {
				taskWriteError(p, stack, err)
				return
			}

			// Call the service method
			result, svcErr := service.ClearQueue(ctx, req.QueueName)
			if svcErr != nil {
				taskWriteError(p, stack, svcErr)
				return
			}

			// Write JSON response to plugin memory
			resp := TaskClearQueueResponse{
				Result: result,
			}
			taskWriteResponse(p, stack, resp)
		},
		[]extism.ValueType{extism.ValueTypePTR},
		[]extism.ValueType{extism.ValueTypePTR},
	)
}

// taskWriteResponse writes a JSON response to plugin memory.
func taskWriteResponse(p *extism.CurrentPlugin, stack []uint64, resp any) {
	respBytes, err := json.Marshal(resp)
	if err != nil {
		taskWriteError(p, stack, err)
		return
	}
	respPtr, err := p.WriteBytes(respBytes)
	if err != nil {
		stack[0] = 0
		return
	}
	stack[0] = respPtr
}

// taskWriteError writes an error response to plugin memory.
func taskWriteError(p *extism.CurrentPlugin, stack []uint64, err error) {
	errResp := struct {
		Error string `json:"error"`
	}{Error: err.Error()}
	respBytes, _ := json.Marshal(errResp)
	respPtr, _ := p.WriteBytes(respBytes)
	stack[0] = respPtr
}
