// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Code generated by the Google Gen AI SDK generator DO NOT EDIT.

package genai

import (
	"context"
	"fmt"
	"iter"
	"net/http"
)

func createCachedContentConfigToMldev(ac *apiClient, fromObject map[string]any, parentObject map[string]any) (toObject map[string]any, err error) {
	toObject = make(map[string]any)

	fromTtl := getValueByPath(fromObject, []string{"ttl"})
	if fromTtl != nil {
		setValueByPath(parentObject, []string{"ttl"}, fromTtl)
	}

	fromExpireTime := getValueByPath(fromObject, []string{"expireTime"})
	if fromExpireTime != nil {
		setValueByPath(parentObject, []string{"expireTime"}, fromExpireTime)
	}

	fromDisplayName := getValueByPath(fromObject, []string{"displayName"})
	if fromDisplayName != nil {
		setValueByPath(parentObject, []string{"displayName"}, fromDisplayName)
	}

	fromContents := getValueByPath(fromObject, []string{"contents"})
	if fromContents != nil {
		fromContents, err = tContents(ac, fromContents)
		if err != nil {
			return nil, err
		}

		fromContents, err = applyConverterToSlice(ac, fromContents.([]any), contentToMldev)
		if err != nil {
			return nil, err
		}

		setValueByPath(parentObject, []string{"contents"}, fromContents)
	}

	fromSystemInstruction := getValueByPath(fromObject, []string{"systemInstruction"})
	if fromSystemInstruction != nil {
		fromSystemInstruction, err = tContent(ac, fromSystemInstruction)
		if err != nil {
			return nil, err
		}

		fromSystemInstruction, err = contentToMldev(ac, fromSystemInstruction.(map[string]any), toObject)
		if err != nil {
			return nil, err
		}

		setValueByPath(parentObject, []string{"systemInstruction"}, fromSystemInstruction)
	}

	fromTools := getValueByPath(fromObject, []string{"tools"})
	if fromTools != nil {
		fromTools, err = applyConverterToSlice(ac, fromTools.([]any), toolToMldev)
		if err != nil {
			return nil, err
		}

		setValueByPath(parentObject, []string{"tools"}, fromTools)
	}

	fromToolConfig := getValueByPath(fromObject, []string{"toolConfig"})
	if fromToolConfig != nil {
		fromToolConfig, err = toolConfigToMldev(ac, fromToolConfig.(map[string]any), toObject)
		if err != nil {
			return nil, err
		}

		setValueByPath(parentObject, []string{"toolConfig"}, fromToolConfig)
	}

	return toObject, nil
}

func createCachedContentParametersToMldev(ac *apiClient, fromObject map[string]any, parentObject map[string]any) (toObject map[string]any, err error) {
	toObject = make(map[string]any)

	fromModel := getValueByPath(fromObject, []string{"model"})
	if fromModel != nil {
		fromModel, err = tCachesModel(ac, fromModel)
		if err != nil {
			return nil, err
		}

		setValueByPath(toObject, []string{"model"}, fromModel)
	}

	fromConfig := getValueByPath(fromObject, []string{"config"})
	if fromConfig != nil {
		fromConfig, err = createCachedContentConfigToMldev(ac, fromConfig.(map[string]any), toObject)
		if err != nil {
			return nil, err
		}

		setValueByPath(toObject, []string{"config"}, fromConfig)
	}

	return toObject, nil
}

func getCachedContentParametersToMldev(ac *apiClient, fromObject map[string]any, parentObject map[string]any) (toObject map[string]any, err error) {
	toObject = make(map[string]any)

	fromName := getValueByPath(fromObject, []string{"name"})
	if fromName != nil {
		fromName, err = tCachedContentName(ac, fromName)
		if err != nil {
			return nil, err
		}

		setValueByPath(toObject, []string{"_url", "name"}, fromName)
	}

	fromConfig := getValueByPath(fromObject, []string{"config"})
	if fromConfig != nil {
		setValueByPath(toObject, []string{"config"}, fromConfig)
	}

	return toObject, nil
}

func deleteCachedContentParametersToMldev(ac *apiClient, fromObject map[string]any, parentObject map[string]any) (toObject map[string]any, err error) {
	toObject = make(map[string]any)

	fromName := getValueByPath(fromObject, []string{"name"})
	if fromName != nil {
		fromName, err = tCachedContentName(ac, fromName)
		if err != nil {
			return nil, err
		}

		setValueByPath(toObject, []string{"_url", "name"}, fromName)
	}

	fromConfig := getValueByPath(fromObject, []string{"config"})
	if fromConfig != nil {
		setValueByPath(toObject, []string{"config"}, fromConfig)
	}

	return toObject, nil
}

func updateCachedContentConfigToMldev(ac *apiClient, fromObject map[string]any, parentObject map[string]any) (toObject map[string]any, err error) {
	toObject = make(map[string]any)

	fromTtl := getValueByPath(fromObject, []string{"ttl"})
	if fromTtl != nil {
		setValueByPath(parentObject, []string{"ttl"}, fromTtl)
	}

	fromExpireTime := getValueByPath(fromObject, []string{"expireTime"})
	if fromExpireTime != nil {
		setValueByPath(parentObject, []string{"expireTime"}, fromExpireTime)
	}

	return toObject, nil
}

func updateCachedContentParametersToMldev(ac *apiClient, fromObject map[string]any, parentObject map[string]any) (toObject map[string]any, err error) {
	toObject = make(map[string]any)

	fromName := getValueByPath(fromObject, []string{"name"})
	if fromName != nil {
		fromName, err = tCachedContentName(ac, fromName)
		if err != nil {
			return nil, err
		}

		setValueByPath(toObject, []string{"_url", "name"}, fromName)
	}

	fromConfig := getValueByPath(fromObject, []string{"config"})
	if fromConfig != nil {
		fromConfig, err = updateCachedContentConfigToMldev(ac, fromConfig.(map[string]any), toObject)
		if err != nil {
			return nil, err
		}

		setValueByPath(toObject, []string{"config"}, fromConfig)
	}

	return toObject, nil
}

func listCachedContentsConfigToMldev(ac *apiClient, fromObject map[string]any, parentObject map[string]any) (toObject map[string]any, err error) {
	toObject = make(map[string]any)

	fromPageSize := getValueByPath(fromObject, []string{"pageSize"})
	if fromPageSize != nil {
		setValueByPath(parentObject, []string{"_query", "pageSize"}, fromPageSize)
	}

	fromPageToken := getValueByPath(fromObject, []string{"pageToken"})
	if fromPageToken != nil {
		setValueByPath(parentObject, []string{"_query", "pageToken"}, fromPageToken)
	}

	return toObject, nil
}

func listCachedContentsParametersToMldev(ac *apiClient, fromObject map[string]any, parentObject map[string]any) (toObject map[string]any, err error) {
	toObject = make(map[string]any)

	fromConfig := getValueByPath(fromObject, []string{"config"})
	if fromConfig != nil {
		fromConfig, err = listCachedContentsConfigToMldev(ac, fromConfig.(map[string]any), toObject)
		if err != nil {
			return nil, err
		}

		setValueByPath(toObject, []string{"config"}, fromConfig)
	}

	return toObject, nil
}

func createCachedContentConfigToVertex(ac *apiClient, fromObject map[string]any, parentObject map[string]any) (toObject map[string]any, err error) {
	toObject = make(map[string]any)

	fromTtl := getValueByPath(fromObject, []string{"ttl"})
	if fromTtl != nil {
		setValueByPath(parentObject, []string{"ttl"}, fromTtl)
	}

	fromExpireTime := getValueByPath(fromObject, []string{"expireTime"})
	if fromExpireTime != nil {
		setValueByPath(parentObject, []string{"expireTime"}, fromExpireTime)
	}

	fromDisplayName := getValueByPath(fromObject, []string{"displayName"})
	if fromDisplayName != nil {
		setValueByPath(parentObject, []string{"displayName"}, fromDisplayName)
	}

	fromContents := getValueByPath(fromObject, []string{"contents"})
	if fromContents != nil {
		fromContents, err = tContents(ac, fromContents)
		if err != nil {
			return nil, err
		}

		fromContents, err = applyConverterToSlice(ac, fromContents.([]any), contentToVertex)
		if err != nil {
			return nil, err
		}

		setValueByPath(parentObject, []string{"contents"}, fromContents)
	}

	fromSystemInstruction := getValueByPath(fromObject, []string{"systemInstruction"})
	if fromSystemInstruction != nil {
		fromSystemInstruction, err = tContent(ac, fromSystemInstruction)
		if err != nil {
			return nil, err
		}

		fromSystemInstruction, err = contentToVertex(ac, fromSystemInstruction.(map[string]any), toObject)
		if err != nil {
			return nil, err
		}

		setValueByPath(parentObject, []string{"systemInstruction"}, fromSystemInstruction)
	}

	fromTools := getValueByPath(fromObject, []string{"tools"})
	if fromTools != nil {
		fromTools, err = applyConverterToSlice(ac, fromTools.([]any), toolToVertex)
		if err != nil {
			return nil, err
		}

		setValueByPath(parentObject, []string{"tools"}, fromTools)
	}

	fromToolConfig := getValueByPath(fromObject, []string{"toolConfig"})
	if fromToolConfig != nil {
		fromToolConfig, err = toolConfigToVertex(ac, fromToolConfig.(map[string]any), toObject)
		if err != nil {
			return nil, err
		}

		setValueByPath(parentObject, []string{"toolConfig"}, fromToolConfig)
	}

	return toObject, nil
}

func createCachedContentParametersToVertex(ac *apiClient, fromObject map[string]any, parentObject map[string]any) (toObject map[string]any, err error) {
	toObject = make(map[string]any)

	fromModel := getValueByPath(fromObject, []string{"model"})
	if fromModel != nil {
		fromModel, err = tCachesModel(ac, fromModel)
		if err != nil {
			return nil, err
		}

		setValueByPath(toObject, []string{"model"}, fromModel)
	}

	fromConfig := getValueByPath(fromObject, []string{"config"})
	if fromConfig != nil {
		fromConfig, err = createCachedContentConfigToVertex(ac, fromConfig.(map[string]any), toObject)
		if err != nil {
			return nil, err
		}

		setValueByPath(toObject, []string{"config"}, fromConfig)
	}

	return toObject, nil
}

func getCachedContentParametersToVertex(ac *apiClient, fromObject map[string]any, parentObject map[string]any) (toObject map[string]any, err error) {
	toObject = make(map[string]any)

	fromName := getValueByPath(fromObject, []string{"name"})
	if fromName != nil {
		fromName, err = tCachedContentName(ac, fromName)
		if err != nil {
			return nil, err
		}

		setValueByPath(toObject, []string{"_url", "name"}, fromName)
	}

	fromConfig := getValueByPath(fromObject, []string{"config"})
	if fromConfig != nil {
		setValueByPath(toObject, []string{"config"}, fromConfig)
	}

	return toObject, nil
}

func deleteCachedContentParametersToVertex(ac *apiClient, fromObject map[string]any, parentObject map[string]any) (toObject map[string]any, err error) {
	toObject = make(map[string]any)

	fromName := getValueByPath(fromObject, []string{"name"})
	if fromName != nil {
		fromName, err = tCachedContentName(ac, fromName)
		if err != nil {
			return nil, err
		}

		setValueByPath(toObject, []string{"_url", "name"}, fromName)
	}

	fromConfig := getValueByPath(fromObject, []string{"config"})
	if fromConfig != nil {
		setValueByPath(toObject, []string{"config"}, fromConfig)
	}

	return toObject, nil
}

func updateCachedContentConfigToVertex(ac *apiClient, fromObject map[string]any, parentObject map[string]any) (toObject map[string]any, err error) {
	toObject = make(map[string]any)

	fromTtl := getValueByPath(fromObject, []string{"ttl"})
	if fromTtl != nil {
		setValueByPath(parentObject, []string{"ttl"}, fromTtl)
	}

	fromExpireTime := getValueByPath(fromObject, []string{"expireTime"})
	if fromExpireTime != nil {
		setValueByPath(parentObject, []string{"expireTime"}, fromExpireTime)
	}

	return toObject, nil
}

func updateCachedContentParametersToVertex(ac *apiClient, fromObject map[string]any, parentObject map[string]any) (toObject map[string]any, err error) {
	toObject = make(map[string]any)

	fromName := getValueByPath(fromObject, []string{"name"})
	if fromName != nil {
		fromName, err = tCachedContentName(ac, fromName)
		if err != nil {
			return nil, err
		}

		setValueByPath(toObject, []string{"_url", "name"}, fromName)
	}

	fromConfig := getValueByPath(fromObject, []string{"config"})
	if fromConfig != nil {
		fromConfig, err = updateCachedContentConfigToVertex(ac, fromConfig.(map[string]any), toObject)
		if err != nil {
			return nil, err
		}

		setValueByPath(toObject, []string{"config"}, fromConfig)
	}

	return toObject, nil
}

func listCachedContentsConfigToVertex(ac *apiClient, fromObject map[string]any, parentObject map[string]any) (toObject map[string]any, err error) {
	toObject = make(map[string]any)

	fromPageSize := getValueByPath(fromObject, []string{"pageSize"})
	if fromPageSize != nil {
		setValueByPath(parentObject, []string{"_query", "pageSize"}, fromPageSize)
	}

	fromPageToken := getValueByPath(fromObject, []string{"pageToken"})
	if fromPageToken != nil {
		setValueByPath(parentObject, []string{"_query", "pageToken"}, fromPageToken)
	}

	return toObject, nil
}

func listCachedContentsParametersToVertex(ac *apiClient, fromObject map[string]any, parentObject map[string]any) (toObject map[string]any, err error) {
	toObject = make(map[string]any)

	fromConfig := getValueByPath(fromObject, []string{"config"})
	if fromConfig != nil {
		fromConfig, err = listCachedContentsConfigToVertex(ac, fromConfig.(map[string]any), toObject)
		if err != nil {
			return nil, err
		}

		setValueByPath(toObject, []string{"config"}, fromConfig)
	}

	return toObject, nil
}

func cachedContentFromMldev(ac *apiClient, fromObject map[string]any, parentObject map[string]any) (toObject map[string]any, err error) {
	toObject = make(map[string]any)

	fromName := getValueByPath(fromObject, []string{"name"})
	if fromName != nil {
		setValueByPath(toObject, []string{"name"}, fromName)
	}

	fromDisplayName := getValueByPath(fromObject, []string{"displayName"})
	if fromDisplayName != nil {
		setValueByPath(toObject, []string{"displayName"}, fromDisplayName)
	}

	fromModel := getValueByPath(fromObject, []string{"model"})
	if fromModel != nil {
		setValueByPath(toObject, []string{"model"}, fromModel)
	}

	fromCreateTime := getValueByPath(fromObject, []string{"createTime"})
	if fromCreateTime != nil {
		setValueByPath(toObject, []string{"createTime"}, fromCreateTime)
	}

	fromUpdateTime := getValueByPath(fromObject, []string{"updateTime"})
	if fromUpdateTime != nil {
		setValueByPath(toObject, []string{"updateTime"}, fromUpdateTime)
	}

	fromExpireTime := getValueByPath(fromObject, []string{"expireTime"})
	if fromExpireTime != nil {
		setValueByPath(toObject, []string{"expireTime"}, fromExpireTime)
	}

	fromUsageMetadata := getValueByPath(fromObject, []string{"usageMetadata"})
	if fromUsageMetadata != nil {
		setValueByPath(toObject, []string{"usageMetadata"}, fromUsageMetadata)
	}

	return toObject, nil
}

func deleteCachedContentResponseFromMldev(ac *apiClient, fromObject map[string]any, parentObject map[string]any) (toObject map[string]any, err error) {
	toObject = make(map[string]any)

	return toObject, nil
}

func listCachedContentsResponseFromMldev(ac *apiClient, fromObject map[string]any, parentObject map[string]any) (toObject map[string]any, err error) {
	toObject = make(map[string]any)

	fromNextPageToken := getValueByPath(fromObject, []string{"nextPageToken"})
	if fromNextPageToken != nil {
		setValueByPath(toObject, []string{"nextPageToken"}, fromNextPageToken)
	}

	fromCachedContents := getValueByPath(fromObject, []string{"cachedContents"})
	if fromCachedContents != nil {
		fromCachedContents, err = applyConverterToSlice(ac, fromCachedContents.([]any), cachedContentFromMldev)
		if err != nil {
			return nil, err
		}

		setValueByPath(toObject, []string{"cachedContents"}, fromCachedContents)
	}

	return toObject, nil
}

func cachedContentFromVertex(ac *apiClient, fromObject map[string]any, parentObject map[string]any) (toObject map[string]any, err error) {
	toObject = make(map[string]any)

	fromName := getValueByPath(fromObject, []string{"name"})
	if fromName != nil {
		setValueByPath(toObject, []string{"name"}, fromName)
	}

	fromDisplayName := getValueByPath(fromObject, []string{"displayName"})
	if fromDisplayName != nil {
		setValueByPath(toObject, []string{"displayName"}, fromDisplayName)
	}

	fromModel := getValueByPath(fromObject, []string{"model"})
	if fromModel != nil {
		setValueByPath(toObject, []string{"model"}, fromModel)
	}

	fromCreateTime := getValueByPath(fromObject, []string{"createTime"})
	if fromCreateTime != nil {
		setValueByPath(toObject, []string{"createTime"}, fromCreateTime)
	}

	fromUpdateTime := getValueByPath(fromObject, []string{"updateTime"})
	if fromUpdateTime != nil {
		setValueByPath(toObject, []string{"updateTime"}, fromUpdateTime)
	}

	fromExpireTime := getValueByPath(fromObject, []string{"expireTime"})
	if fromExpireTime != nil {
		setValueByPath(toObject, []string{"expireTime"}, fromExpireTime)
	}

	fromUsageMetadata := getValueByPath(fromObject, []string{"usageMetadata"})
	if fromUsageMetadata != nil {
		setValueByPath(toObject, []string{"usageMetadata"}, fromUsageMetadata)
	}

	return toObject, nil
}

func deleteCachedContentResponseFromVertex(ac *apiClient, fromObject map[string]any, parentObject map[string]any) (toObject map[string]any, err error) {
	toObject = make(map[string]any)

	return toObject, nil
}

func listCachedContentsResponseFromVertex(ac *apiClient, fromObject map[string]any, parentObject map[string]any) (toObject map[string]any, err error) {
	toObject = make(map[string]any)

	fromNextPageToken := getValueByPath(fromObject, []string{"nextPageToken"})
	if fromNextPageToken != nil {
		setValueByPath(toObject, []string{"nextPageToken"}, fromNextPageToken)
	}

	fromCachedContents := getValueByPath(fromObject, []string{"cachedContents"})
	if fromCachedContents != nil {
		fromCachedContents, err = applyConverterToSlice(ac, fromCachedContents.([]any), cachedContentFromVertex)
		if err != nil {
			return nil, err
		}

		setValueByPath(toObject, []string{"cachedContents"}, fromCachedContents)
	}

	return toObject, nil
}

// Caches provides methods for managing the context caching.
// You don't need to initiate this struct. Create a client instance via NewClient, and
// then access Caches through client.Caches field.
type Caches struct {
	apiClient *apiClient
}

// Create creates a new cached content resource.
func (m Caches) Create(ctx context.Context, model string, config *CreateCachedContentConfig) (*CachedContent, error) {
	parameterMap := make(map[string]any)

	kwargs := map[string]any{"model": model, "config": config}
	deepMarshal(kwargs, &parameterMap)

	var httpOptions *HTTPOptions
	if config == nil {
		httpOptions = mergeHTTPOptions(m.apiClient.clientConfig, nil)
	} else {
		httpOptions = mergeHTTPOptions(m.apiClient.clientConfig, config.HTTPOptions)
		config.HTTPOptions = nil
	}
	var response = new(CachedContent)
	var responseMap map[string]any
	var fromConverter func(*apiClient, map[string]any, map[string]any) (map[string]any, error)
	var toConverter func(*apiClient, map[string]any, map[string]any) (map[string]any, error)
	if m.apiClient.clientConfig.Backend == BackendVertexAI {
		toConverter = createCachedContentParametersToVertex
		fromConverter = cachedContentFromVertex
	} else {
		toConverter = createCachedContentParametersToMldev
		fromConverter = cachedContentFromMldev
	}

	body, err := toConverter(m.apiClient, parameterMap, nil)
	if err != nil {
		return nil, err
	}
	var path string
	var urlParams map[string]any
	if _, ok := body["_url"]; ok {
		urlParams = body["_url"].(map[string]any)
		delete(body, "_url")
	}
	if m.apiClient.clientConfig.Backend == BackendVertexAI {
		path, err = formatMap("cachedContents", urlParams)
	} else {
		path, err = formatMap("cachedContents", urlParams)
	}
	if err != nil {
		return nil, fmt.Errorf("invalid url params: %#v.\n%w", urlParams, err)
	}
	if _, ok := body["_query"]; ok {
		query, err := createURLQuery(body["_query"].(map[string]any))
		if err != nil {
			return nil, err
		}
		path += "?" + query
		delete(body, "_query")
	}

	if _, ok := body["config"]; ok {
		delete(body, "config")
	}
	responseMap, err = sendRequest(ctx, m.apiClient, path, http.MethodPost, body, httpOptions)
	if err != nil {
		return nil, err
	}
	responseMap, err = fromConverter(m.apiClient, responseMap, nil)
	if err != nil {
		return nil, err
	}
	err = mapToStruct(responseMap, response)
	if err != nil {
		return nil, err
	}
	return response, nil
}

// Get gets a cached content resource.
func (m Caches) Get(ctx context.Context, name string, config *GetCachedContentConfig) (*CachedContent, error) {
	parameterMap := make(map[string]any)

	kwargs := map[string]any{"name": name, "config": config}
	deepMarshal(kwargs, &parameterMap)

	var httpOptions *HTTPOptions
	if config == nil {
		httpOptions = mergeHTTPOptions(m.apiClient.clientConfig, nil)
	} else {
		httpOptions = mergeHTTPOptions(m.apiClient.clientConfig, config.HTTPOptions)
		config.HTTPOptions = nil
	}
	var response = new(CachedContent)
	var responseMap map[string]any
	var fromConverter func(*apiClient, map[string]any, map[string]any) (map[string]any, error)
	var toConverter func(*apiClient, map[string]any, map[string]any) (map[string]any, error)
	if m.apiClient.clientConfig.Backend == BackendVertexAI {
		toConverter = getCachedContentParametersToVertex
		fromConverter = cachedContentFromVertex
	} else {
		toConverter = getCachedContentParametersToMldev
		fromConverter = cachedContentFromMldev
	}

	body, err := toConverter(m.apiClient, parameterMap, nil)
	if err != nil {
		return nil, err
	}
	var path string
	var urlParams map[string]any
	if _, ok := body["_url"]; ok {
		urlParams = body["_url"].(map[string]any)
		delete(body, "_url")
	}
	if m.apiClient.clientConfig.Backend == BackendVertexAI {
		path, err = formatMap("{name}", urlParams)
	} else {
		path, err = formatMap("{name}", urlParams)
	}
	if err != nil {
		return nil, fmt.Errorf("invalid url params: %#v.\n%w", urlParams, err)
	}
	if _, ok := body["_query"]; ok {
		query, err := createURLQuery(body["_query"].(map[string]any))
		if err != nil {
			return nil, err
		}
		path += "?" + query
		delete(body, "_query")
	}

	if _, ok := body["config"]; ok {
		delete(body, "config")
	}
	responseMap, err = sendRequest(ctx, m.apiClient, path, http.MethodGet, body, httpOptions)
	if err != nil {
		return nil, err
	}
	responseMap, err = fromConverter(m.apiClient, responseMap, nil)
	if err != nil {
		return nil, err
	}
	err = mapToStruct(responseMap, response)
	if err != nil {
		return nil, err
	}
	return response, nil
}

// Delete deletes a cached content resource.
func (m Caches) Delete(ctx context.Context, name string, config *DeleteCachedContentConfig) (*DeleteCachedContentResponse, error) {
	parameterMap := make(map[string]any)

	kwargs := map[string]any{"name": name, "config": config}
	deepMarshal(kwargs, &parameterMap)

	var httpOptions *HTTPOptions
	if config == nil {
		httpOptions = mergeHTTPOptions(m.apiClient.clientConfig, nil)
	} else {
		httpOptions = mergeHTTPOptions(m.apiClient.clientConfig, config.HTTPOptions)
		config.HTTPOptions = nil
	}
	var response = new(DeleteCachedContentResponse)
	var responseMap map[string]any
	var fromConverter func(*apiClient, map[string]any, map[string]any) (map[string]any, error)
	var toConverter func(*apiClient, map[string]any, map[string]any) (map[string]any, error)
	if m.apiClient.clientConfig.Backend == BackendVertexAI {
		toConverter = deleteCachedContentParametersToVertex
		fromConverter = deleteCachedContentResponseFromVertex
	} else {
		toConverter = deleteCachedContentParametersToMldev
		fromConverter = deleteCachedContentResponseFromMldev
	}

	body, err := toConverter(m.apiClient, parameterMap, nil)
	if err != nil {
		return nil, err
	}
	var path string
	var urlParams map[string]any
	if _, ok := body["_url"]; ok {
		urlParams = body["_url"].(map[string]any)
		delete(body, "_url")
	}
	if m.apiClient.clientConfig.Backend == BackendVertexAI {
		path, err = formatMap("{name}", urlParams)
	} else {
		path, err = formatMap("{name}", urlParams)
	}
	if err != nil {
		return nil, fmt.Errorf("invalid url params: %#v.\n%w", urlParams, err)
	}
	if _, ok := body["_query"]; ok {
		query, err := createURLQuery(body["_query"].(map[string]any))
		if err != nil {
			return nil, err
		}
		path += "?" + query
		delete(body, "_query")
	}

	if _, ok := body["config"]; ok {
		delete(body, "config")
	}
	responseMap, err = sendRequest(ctx, m.apiClient, path, http.MethodDelete, body, httpOptions)
	if err != nil {
		return nil, err
	}
	responseMap, err = fromConverter(m.apiClient, responseMap, nil)
	if err != nil {
		return nil, err
	}
	err = mapToStruct(responseMap, response)
	if err != nil {
		return nil, err
	}
	return response, nil
}

// Update updates a cached content resource.
func (m Caches) Update(ctx context.Context, name string, config *UpdateCachedContentConfig) (*CachedContent, error) {
	parameterMap := make(map[string]any)

	kwargs := map[string]any{"name": name, "config": config}
	deepMarshal(kwargs, &parameterMap)

	var httpOptions *HTTPOptions
	if config == nil {
		httpOptions = mergeHTTPOptions(m.apiClient.clientConfig, nil)
	} else {
		httpOptions = mergeHTTPOptions(m.apiClient.clientConfig, config.HTTPOptions)
		config.HTTPOptions = nil
	}
	var response = new(CachedContent)
	var responseMap map[string]any
	var fromConverter func(*apiClient, map[string]any, map[string]any) (map[string]any, error)
	var toConverter func(*apiClient, map[string]any, map[string]any) (map[string]any, error)
	if m.apiClient.clientConfig.Backend == BackendVertexAI {
		toConverter = updateCachedContentParametersToVertex
		fromConverter = cachedContentFromVertex
	} else {
		toConverter = updateCachedContentParametersToMldev
		fromConverter = cachedContentFromMldev
	}

	body, err := toConverter(m.apiClient, parameterMap, nil)
	if err != nil {
		return nil, err
	}
	var path string
	var urlParams map[string]any
	if _, ok := body["_url"]; ok {
		urlParams = body["_url"].(map[string]any)
		delete(body, "_url")
	}
	if m.apiClient.clientConfig.Backend == BackendVertexAI {
		path, err = formatMap("{name}", urlParams)
	} else {
		path, err = formatMap("{name}", urlParams)
	}
	if err != nil {
		return nil, fmt.Errorf("invalid url params: %#v.\n%w", urlParams, err)
	}
	if _, ok := body["_query"]; ok {
		query, err := createURLQuery(body["_query"].(map[string]any))
		if err != nil {
			return nil, err
		}
		path += "?" + query
		delete(body, "_query")
	}

	if _, ok := body["config"]; ok {
		delete(body, "config")
	}
	responseMap, err = sendRequest(ctx, m.apiClient, path, http.MethodPatch, body, httpOptions)
	if err != nil {
		return nil, err
	}
	responseMap, err = fromConverter(m.apiClient, responseMap, nil)
	if err != nil {
		return nil, err
	}
	err = mapToStruct(responseMap, response)
	if err != nil {
		return nil, err
	}
	return response, nil
}

func (m Caches) list(ctx context.Context, config *ListCachedContentsConfig) (*ListCachedContentsResponse, error) {
	parameterMap := make(map[string]any)

	kwargs := map[string]any{"config": config}
	deepMarshal(kwargs, &parameterMap)

	var httpOptions *HTTPOptions
	if config == nil {
		httpOptions = mergeHTTPOptions(m.apiClient.clientConfig, nil)
	} else {
		httpOptions = mergeHTTPOptions(m.apiClient.clientConfig, config.HTTPOptions)
		config.HTTPOptions = nil
	}
	var response = new(ListCachedContentsResponse)
	var responseMap map[string]any
	var fromConverter func(*apiClient, map[string]any, map[string]any) (map[string]any, error)
	var toConverter func(*apiClient, map[string]any, map[string]any) (map[string]any, error)
	if m.apiClient.clientConfig.Backend == BackendVertexAI {
		toConverter = listCachedContentsParametersToVertex
		fromConverter = listCachedContentsResponseFromVertex
	} else {
		toConverter = listCachedContentsParametersToMldev
		fromConverter = listCachedContentsResponseFromMldev
	}

	body, err := toConverter(m.apiClient, parameterMap, nil)
	if err != nil {
		return nil, err
	}
	var path string
	var urlParams map[string]any
	if _, ok := body["_url"]; ok {
		urlParams = body["_url"].(map[string]any)
		delete(body, "_url")
	}
	if m.apiClient.clientConfig.Backend == BackendVertexAI {
		path, err = formatMap("cachedContents", urlParams)
	} else {
		path, err = formatMap("cachedContents", urlParams)
	}
	if err != nil {
		return nil, fmt.Errorf("invalid url params: %#v.\n%w", urlParams, err)
	}
	if _, ok := body["_query"]; ok {
		query, err := createURLQuery(body["_query"].(map[string]any))
		if err != nil {
			return nil, err
		}
		path += "?" + query
		delete(body, "_query")
	}

	if _, ok := body["config"]; ok {
		delete(body, "config")
	}
	responseMap, err = sendRequest(ctx, m.apiClient, path, http.MethodGet, body, httpOptions)
	if err != nil {
		return nil, err
	}
	responseMap, err = fromConverter(m.apiClient, responseMap, nil)
	if err != nil {
		return nil, err
	}
	err = mapToStruct(responseMap, response)
	if err != nil {
		return nil, err
	}
	return response, nil
}

// List retrieves a paginated list of cached content resources.
func (m Caches) List(ctx context.Context, config *ListCachedContentsConfig) (Page[CachedContent], error) {
	listFunc := func(ctx context.Context, config map[string]any) ([]*CachedContent, string, error) {
		var c ListCachedContentsConfig
		if err := mapToStruct(config, &c); err != nil {
			return nil, "", err
		}
		resp, err := m.list(ctx, &c)
		if err != nil {
			return nil, "", err
		}
		return resp.CachedContents, resp.NextPageToken, nil
	}
	c := make(map[string]any)
	deepMarshal(config, &c)
	return newPage(ctx, "cachedContents", c, listFunc)
}

// All retrieves all cached content resources.
//
// This method handles pagination internally, making multiple API calls as needed
// to fetch all entries. It returns an iterator that yields each cached
// content entry one by one. You do not need to manage pagination
// tokens or make multiple calls to retrieve all data.
func (m Caches) All(ctx context.Context) iter.Seq2[*CachedContent, error] {
	listFunc := func(ctx context.Context, config map[string]any) ([]*CachedContent, string, error) {
		var c ListCachedContentsConfig
		if err := mapToStruct(config, &c); err != nil {
			return nil, "", err
		}
		resp, err := m.list(ctx, &c)
		if err != nil {
			return nil, "", err
		}
		return resp.CachedContents, resp.NextPageToken, nil
	}
	p, err := newPage(ctx, "cachedContents", map[string]any{}, listFunc)
	if err != nil {
		return yieldErrorAndEndIterator[CachedContent](err)
	}
	return p.all(ctx)
}
