// Code generated by ndpgen. DO NOT EDIT.

package host

import (
	"context"
	"encoding/json"

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

// CacheSetStringRequest is the request type for Cache.SetString.
type CacheSetStringRequest struct {
	Key        string `json:"key"`
	Value      string `json:"value"`
	TtlSeconds int64  `json:"ttlSeconds"`
}

// CacheSetStringResponse is the response type for Cache.SetString.
type CacheSetStringResponse struct {
	Error string `json:"error,omitempty"`
}

// CacheGetStringRequest is the request type for Cache.GetString.
type CacheGetStringRequest struct {
	Key string `json:"key"`
}

// CacheGetStringResponse is the response type for Cache.GetString.
type CacheGetStringResponse struct {
	Value  string `json:"value,omitempty"`
	Exists bool   `json:"exists,omitempty"`
	Error  string `json:"error,omitempty"`
}

// CacheSetIntRequest is the request type for Cache.SetInt.
type CacheSetIntRequest struct {
	Key        string `json:"key"`
	Value      int64  `json:"value"`
	TtlSeconds int64  `json:"ttlSeconds"`
}

// CacheSetIntResponse is the response type for Cache.SetInt.
type CacheSetIntResponse struct {
	Error string `json:"error,omitempty"`
}

// CacheGetIntRequest is the request type for Cache.GetInt.
type CacheGetIntRequest struct {
	Key string `json:"key"`
}

// CacheGetIntResponse is the response type for Cache.GetInt.
type CacheGetIntResponse struct {
	Value  int64  `json:"value,omitempty"`
	Exists bool   `json:"exists,omitempty"`
	Error  string `json:"error,omitempty"`
}

// CacheSetFloatRequest is the request type for Cache.SetFloat.
type CacheSetFloatRequest struct {
	Key        string  `json:"key"`
	Value      float64 `json:"value"`
	TtlSeconds int64   `json:"ttlSeconds"`
}

// CacheSetFloatResponse is the response type for Cache.SetFloat.
type CacheSetFloatResponse struct {
	Error string `json:"error,omitempty"`
}

// CacheGetFloatRequest is the request type for Cache.GetFloat.
type CacheGetFloatRequest struct {
	Key string `json:"key"`
}

// CacheGetFloatResponse is the response type for Cache.GetFloat.
type CacheGetFloatResponse struct {
	Value  float64 `json:"value,omitempty"`
	Exists bool    `json:"exists,omitempty"`
	Error  string  `json:"error,omitempty"`
}

// CacheSetBytesRequest is the request type for Cache.SetBytes.
type CacheSetBytesRequest struct {
	Key        string `json:"key"`
	Value      []byte `json:"value"`
	TtlSeconds int64  `json:"ttlSeconds"`
}

// CacheSetBytesResponse is the response type for Cache.SetBytes.
type CacheSetBytesResponse struct {
	Error string `json:"error,omitempty"`
}

// CacheGetBytesRequest is the request type for Cache.GetBytes.
type CacheGetBytesRequest struct {
	Key string `json:"key"`
}

// CacheGetBytesResponse is the response type for Cache.GetBytes.
type CacheGetBytesResponse struct {
	Value  []byte `json:"value,omitempty"`
	Exists bool   `json:"exists,omitempty"`
	Error  string `json:"error,omitempty"`
}

// CacheHasRequest is the request type for Cache.Has.
type CacheHasRequest struct {
	Key string `json:"key"`
}

// CacheHasResponse is the response type for Cache.Has.
type CacheHasResponse struct {
	Exists bool   `json:"exists,omitempty"`
	Error  string `json:"error,omitempty"`
}

// CacheRemoveRequest is the request type for Cache.Remove.
type CacheRemoveRequest struct {
	Key string `json:"key"`
}

// CacheRemoveResponse is the response type for Cache.Remove.
type CacheRemoveResponse struct {
	Error string `json:"error,omitempty"`
}

// RegisterCacheHostFunctions registers Cache service host functions.
// The returned host functions should be added to the plugin's configuration.
func RegisterCacheHostFunctions(service CacheService) []extism.HostFunction {
	return []extism.HostFunction{
		newCacheSetStringHostFunction(service),
		newCacheGetStringHostFunction(service),
		newCacheSetIntHostFunction(service),
		newCacheGetIntHostFunction(service),
		newCacheSetFloatHostFunction(service),
		newCacheGetFloatHostFunction(service),
		newCacheSetBytesHostFunction(service),
		newCacheGetBytesHostFunction(service),
		newCacheHasHostFunction(service),
		newCacheRemoveHostFunction(service),
	}
}

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

			// Call the service method
			if svcErr := service.SetString(ctx, req.Key, req.Value, req.TtlSeconds); svcErr != nil {
				cacheWriteError(p, stack, svcErr)
				return
			}

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

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

			// Call the service method
			value, exists, svcErr := service.GetString(ctx, req.Key)
			if svcErr != nil {
				cacheWriteError(p, stack, svcErr)
				return
			}

			// Write JSON response to plugin memory
			resp := CacheGetStringResponse{
				Value:  value,
				Exists: exists,
			}
			cacheWriteResponse(p, stack, resp)
		},
		[]extism.ValueType{extism.ValueTypePTR},
		[]extism.ValueType{extism.ValueTypePTR},
	)
}

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

			// Call the service method
			if svcErr := service.SetInt(ctx, req.Key, req.Value, req.TtlSeconds); svcErr != nil {
				cacheWriteError(p, stack, svcErr)
				return
			}

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

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

			// Call the service method
			value, exists, svcErr := service.GetInt(ctx, req.Key)
			if svcErr != nil {
				cacheWriteError(p, stack, svcErr)
				return
			}

			// Write JSON response to plugin memory
			resp := CacheGetIntResponse{
				Value:  value,
				Exists: exists,
			}
			cacheWriteResponse(p, stack, resp)
		},
		[]extism.ValueType{extism.ValueTypePTR},
		[]extism.ValueType{extism.ValueTypePTR},
	)
}

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

			// Call the service method
			if svcErr := service.SetFloat(ctx, req.Key, req.Value, req.TtlSeconds); svcErr != nil {
				cacheWriteError(p, stack, svcErr)
				return
			}

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

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

			// Call the service method
			value, exists, svcErr := service.GetFloat(ctx, req.Key)
			if svcErr != nil {
				cacheWriteError(p, stack, svcErr)
				return
			}

			// Write JSON response to plugin memory
			resp := CacheGetFloatResponse{
				Value:  value,
				Exists: exists,
			}
			cacheWriteResponse(p, stack, resp)
		},
		[]extism.ValueType{extism.ValueTypePTR},
		[]extism.ValueType{extism.ValueTypePTR},
	)
}

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

			// Call the service method
			if svcErr := service.SetBytes(ctx, req.Key, req.Value, req.TtlSeconds); svcErr != nil {
				cacheWriteError(p, stack, svcErr)
				return
			}

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

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

			// Call the service method
			value, exists, svcErr := service.GetBytes(ctx, req.Key)
			if svcErr != nil {
				cacheWriteError(p, stack, svcErr)
				return
			}

			// Write JSON response to plugin memory
			resp := CacheGetBytesResponse{
				Value:  value,
				Exists: exists,
			}
			cacheWriteResponse(p, stack, resp)
		},
		[]extism.ValueType{extism.ValueTypePTR},
		[]extism.ValueType{extism.ValueTypePTR},
	)
}

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

			// Call the service method
			exists, svcErr := service.Has(ctx, req.Key)
			if svcErr != nil {
				cacheWriteError(p, stack, svcErr)
				return
			}

			// Write JSON response to plugin memory
			resp := CacheHasResponse{
				Exists: exists,
			}
			cacheWriteResponse(p, stack, resp)
		},
		[]extism.ValueType{extism.ValueTypePTR},
		[]extism.ValueType{extism.ValueTypePTR},
	)
}

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

			// Call the service method
			if svcErr := service.Remove(ctx, req.Key); svcErr != nil {
				cacheWriteError(p, stack, svcErr)
				return
			}

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

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

// cacheWriteError writes an error response to plugin memory.
func cacheWriteError(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
}
