// Package v3 provides primitives to interact with the openapi HTTP API.
//
// Code generated by github.com/egoscale/v3/generator version v0.0.1 DO NOT EDIT.
package v3

import (
	"context"
	"fmt"
	"net"
	"net/http"
	"net/url"
	"time"
)

// FindListAIAPIKeysResponseEntry attempts to find an ListAIAPIKeysResponseEntry by nameOrID.
func (l ListAIAPIKeysResponse) FindListAIAPIKeysResponseEntry(nameOrID string) (ListAIAPIKeysResponseEntry, error) {
	var result []ListAIAPIKeysResponseEntry
	for i, elem := range l.AIAPIKeys {
		if string(elem.Name) == nameOrID || string(elem.ID) == nameOrID {
			result = append(result, l.AIAPIKeys[i])
		}
	}
	if len(result) == 1 {
		return result[0], nil
	}

	if len(result) > 1 {
		return ListAIAPIKeysResponseEntry{}, fmt.Errorf("%q too many found in ListAIAPIKeysResponse: %w", nameOrID, ErrConflict)
	}

	return ListAIAPIKeysResponseEntry{}, fmt.Errorf("%q not found in ListAIAPIKeysResponse: %w", nameOrID, ErrNotFound)
}

// List AI API keys for an organization
func (c Client) ListAIAPIKeys(ctx context.Context) (*ListAIAPIKeysResponse, error) {
	path := "/ai/api-key"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListAIAPIKeys: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListAIAPIKeys: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListAIAPIKeys: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-ai-api-keys")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListAIAPIKeys: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListAIAPIKeys: http response: %w", err)
	}

	bodyresp := new(ListAIAPIKeysResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListAIAPIKeys: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Create a new AI API key
func (c Client) CreateAIAPIKey(ctx context.Context, req CreateAIAPIKeyRequest) (*CreateAIAPIKeyResponse, error) {
	path := "/ai/api-key"

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateAIAPIKey: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateAIAPIKey: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateAIAPIKey: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateAIAPIKey: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-ai-api-key")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateAIAPIKey: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateAIAPIKey: http response: %w", err)
	}

	bodyresp := new(CreateAIAPIKeyResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateAIAPIKey: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Delete AI API key
func (c Client) DeleteAIAPIKey(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/ai/api-key/%v", id)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteAIAPIKey: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteAIAPIKey: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteAIAPIKey: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-ai-api-key")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteAIAPIKey: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteAIAPIKey: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteAIAPIKey: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Get AI API key metadata
func (c Client) GetAIAPIKey(ctx context.Context, id UUID) (*GetAIAPIKeyResponse, error) {
	path := fmt.Sprintf("/ai/api-key/%v", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetAIAPIKey: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetAIAPIKey: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetAIAPIKey: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-ai-api-key")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetAIAPIKey: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetAIAPIKey: http response: %w", err)
	}

	bodyresp := new(GetAIAPIKeyResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetAIAPIKey: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Update AI API key name and/or scope
func (c Client) UpdateAIAPIKey(ctx context.Context, id UUID, req UpdateAIAPIKeyRequest) (*UpdateAIAPIKeyResponse, error) {
	path := fmt.Sprintf("/ai/api-key/%v", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateAIAPIKey: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PATCH", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateAIAPIKey: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateAIAPIKey: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateAIAPIKey: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-ai-api-key")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateAIAPIKey: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateAIAPIKey: http response: %w", err)
	}

	bodyresp := new(UpdateAIAPIKeyResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateAIAPIKey: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Reveal AI API key plaintext value
func (c Client) RevealAIAPIKey(ctx context.Context, id UUID) (*RevealAIAPIKeyResponse, error) {
	path := fmt.Sprintf("/ai/api-key/%v/reveal", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("RevealAIAPIKey: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("RevealAIAPIKey: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("RevealAIAPIKey: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reveal-ai-api-key")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("RevealAIAPIKey: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("RevealAIAPIKey: http response: %w", err)
	}

	bodyresp := new(RevealAIAPIKeyResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("RevealAIAPIKey: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Rotate AI API key value
func (c Client) RotateAIAPIKey(ctx context.Context, id UUID) (*RotateAIAPIKeyResponse, error) {
	path := fmt.Sprintf("/ai/api-key/%v/rotate", id)

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("RotateAIAPIKey: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("RotateAIAPIKey: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("RotateAIAPIKey: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "rotate-ai-api-key")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("RotateAIAPIKey: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("RotateAIAPIKey: http response: %w", err)
	}

	bodyresp := new(RotateAIAPIKeyResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("RotateAIAPIKey: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// FindListDeploymentsResponseEntry attempts to find an ListDeploymentsResponseEntry by nameOrID.
func (l ListDeploymentsResponse) FindListDeploymentsResponseEntry(nameOrID string) (ListDeploymentsResponseEntry, error) {
	var result []ListDeploymentsResponseEntry
	for i, elem := range l.Deployments {
		if string(elem.Name) == nameOrID || string(elem.ID) == nameOrID {
			result = append(result, l.Deployments[i])
		}
	}
	if len(result) == 1 {
		return result[0], nil
	}

	if len(result) > 1 {
		return ListDeploymentsResponseEntry{}, fmt.Errorf("%q too many found in ListDeploymentsResponse: %w", nameOrID, ErrConflict)
	}

	return ListDeploymentsResponseEntry{}, fmt.Errorf("%q not found in ListDeploymentsResponse: %w", nameOrID, ErrNotFound)
}

type ListDeploymentsOpt func(url.Values)

func ListDeploymentsWithVisibility(visibility string) ListDeploymentsOpt {
	return func(q url.Values) {
		q.Add("visibility", fmt.Sprint(visibility))
	}
}

// List Deployments
func (c Client) ListDeployments(ctx context.Context, opts ...ListDeploymentsOpt) (*ListDeploymentsResponse, error) {
	path := "/ai/deployment"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListDeployments: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if len(opts) > 0 {
		q := request.URL.Query()
		for _, opt := range opts {
			opt(q)
		}
		request.URL.RawQuery = q.Encode()
	}

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListDeployments: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListDeployments: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-deployments")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListDeployments: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListDeployments: http response: %w", err)
	}

	bodyresp := new(ListDeploymentsResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListDeployments: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Deploy a model on an inference server
func (c Client) CreateDeployment(ctx context.Context, req CreateDeploymentRequest) (*Operation, error) {
	path := "/ai/deployment"

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateDeployment: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateDeployment: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateDeployment: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateDeployment: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-deployment")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateDeployment: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateDeployment: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateDeployment: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Delete Deployment
func (c Client) DeleteDeployment(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/ai/deployment/%v", id)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteDeployment: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteDeployment: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteDeployment: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-deployment")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteDeployment: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteDeployment: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteDeployment: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Get Deployment details
func (c Client) GetDeployment(ctx context.Context, id UUID) (*GetDeploymentResponse, error) {
	path := fmt.Sprintf("/ai/deployment/%v", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDeployment: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDeployment: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDeployment: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-deployment")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDeployment: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDeployment: http response: %w", err)
	}

	bodyresp := new(GetDeploymentResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDeployment: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Update AI deployment
func (c Client) UpdateDeployment(ctx context.Context, id UUID, req UpdateDeploymentRequest) (*Operation, error) {
	path := fmt.Sprintf("/ai/deployment/%v", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateDeployment: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PATCH", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateDeployment: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateDeployment: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateDeployment: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-deployment")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateDeployment: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateDeployment: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateDeployment: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Get Deployment API Key
func (c Client) RevealDeploymentAPIKey(ctx context.Context, id UUID) (*RevealDeploymentAPIKeyResponse, error) {
	path := fmt.Sprintf("/ai/deployment/%v/api-key", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("RevealDeploymentAPIKey: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("RevealDeploymentAPIKey: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("RevealDeploymentAPIKey: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reveal-deployment-api-key")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("RevealDeploymentAPIKey: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("RevealDeploymentAPIKey: http response: %w", err)
	}

	bodyresp := new(RevealDeploymentAPIKeyResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("RevealDeploymentAPIKey: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type GetDeploymentLogsOpt func(url.Values)

func GetDeploymentLogsWithStream(stream bool) GetDeploymentLogsOpt {
	return func(q url.Values) {
		q.Add("stream", fmt.Sprint(stream))
	}
}

func GetDeploymentLogsWithTail(tail int64) GetDeploymentLogsOpt {
	return func(q url.Values) {
		q.Add("tail", fmt.Sprint(tail))
	}
}

// Return logs for the vLLM deployment (deploy/<release-name>--deployment-vllm). Optional ?stream=true to request streaming (may not be supported).
func (c Client) GetDeploymentLogs(ctx context.Context, id UUID, opts ...GetDeploymentLogsOpt) (*GetDeploymentLogsResponse, error) {
	path := fmt.Sprintf("/ai/deployment/%v/logs", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDeploymentLogs: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if len(opts) > 0 {
		q := request.URL.Query()
		for _, opt := range opts {
			opt(q)
		}
		request.URL.RawQuery = q.Encode()
	}

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDeploymentLogs: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDeploymentLogs: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-deployment-logs")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDeploymentLogs: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDeploymentLogs: http response: %w", err)
	}

	bodyresp := new(GetDeploymentLogsResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDeploymentLogs: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Scale Deployment
func (c Client) ScaleDeployment(ctx context.Context, id UUID, req ScaleDeploymentRequest) (*Operation, error) {
	path := fmt.Sprintf("/ai/deployment/%v/scale", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("ScaleDeployment: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("ScaleDeployment: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ScaleDeployment: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ScaleDeployment: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "scale-deployment")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ScaleDeployment: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ScaleDeployment: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ScaleDeployment: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type GetInferenceEngineHelpOpt func(url.Values)

func GetInferenceEngineHelpWithVersion(version string) GetInferenceEngineHelpOpt {
	return func(q url.Values) {
		q.Add("version", fmt.Sprint(version))
	}
}

// Get list of allowed inference engine parameters with their descriptions and allowed values
func (c Client) GetInferenceEngineHelp(ctx context.Context, opts ...GetInferenceEngineHelpOpt) (*GetInferenceEngineHelpResponse, error) {
	path := "/ai/help/inference-engine-parameters"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetInferenceEngineHelp: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if len(opts) > 0 {
		q := request.URL.Query()
		for _, opt := range opts {
			opt(q)
		}
		request.URL.RawQuery = q.Encode()
	}

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetInferenceEngineHelp: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetInferenceEngineHelp: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-inference-engine-help")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetInferenceEngineHelp: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetInferenceEngineHelp: http response: %w", err)
	}

	bodyresp := new(GetInferenceEngineHelpResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetInferenceEngineHelp: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// List available instance types with authorization status based on GPU availability
func (c Client) ListAIInstanceTypes(ctx context.Context) (*ListAIInstanceTypesResponse, error) {
	path := "/ai/instance-type"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListAIInstanceTypes: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListAIInstanceTypes: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListAIInstanceTypes: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-ai-instance-types")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListAIInstanceTypes: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListAIInstanceTypes: http response: %w", err)
	}

	bodyresp := new(ListAIInstanceTypesResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListAIInstanceTypes: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// FindListModelsResponseEntry attempts to find an ListModelsResponseEntry by nameOrID.
func (l ListModelsResponse) FindListModelsResponseEntry(nameOrID string) (ListModelsResponseEntry, error) {
	var result []ListModelsResponseEntry
	for i, elem := range l.Models {
		if string(elem.Name) == nameOrID || string(elem.ID) == nameOrID {
			result = append(result, l.Models[i])
		}
	}
	if len(result) == 1 {
		return result[0], nil
	}

	if len(result) > 1 {
		return ListModelsResponseEntry{}, fmt.Errorf("%q too many found in ListModelsResponse: %w", nameOrID, ErrConflict)
	}

	return ListModelsResponseEntry{}, fmt.Errorf("%q not found in ListModelsResponse: %w", nameOrID, ErrNotFound)
}

// List Models
func (c Client) ListModels(ctx context.Context) (*ListModelsResponse, error) {
	path := "/ai/model"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListModels: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListModels: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListModels: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-models")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListModels: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListModels: http response: %w", err)
	}

	bodyresp := new(ListModelsResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListModels: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Model files will be downloaded from Huggingface.
// If the model is under a license then you must provide a Huggingface access token for an account that signed the license agreement
// If the model is under a license then you must provide a Huggingface access token for an account that signed the license agreement
func (c Client) CreateModel(ctx context.Context, req CreateModelRequest) (*Operation, error) {
	path := "/ai/model"

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateModel: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateModel: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateModel: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateModel: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-model")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateModel: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateModel: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateModel: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Delete Model
func (c Client) DeleteModel(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/ai/model/%v", id)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteModel: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteModel: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteModel: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-model")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteModel: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteModel: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteModel: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Get Model details
func (c Client) GetModel(ctx context.Context, id UUID) (*GetModelResponse, error) {
	path := fmt.Sprintf("/ai/model/%v", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetModel: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetModel: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetModel: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-model")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetModel: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetModel: http response: %w", err)
	}

	bodyresp := new(GetModelResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetModel: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Get per-org Unit Of Measurement (UOM) consumption quota (UOM/min). Null means unlimited. UOM represents weighted units across different AI workloads (e.g., tokens for LLMs, minutes for TTS, pages for OCR).
func (c Client) GetUserOrgConsumptionQuota(ctx context.Context) (*OrgConsumptionQuotaResponse, error) {
	path := "/ai/quota"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetUserOrgConsumptionQuota: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetUserOrgConsumptionQuota: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetUserOrgConsumptionQuota: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-user-org-consumption-quota")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetUserOrgConsumptionQuota: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetUserOrgConsumptionQuota: http response: %w", err)
	}

	bodyresp := new(OrgConsumptionQuotaResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetUserOrgConsumptionQuota: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ListAntiAffinityGroupsResponse struct {
	AntiAffinityGroups []AntiAffinityGroup `json:"anti-affinity-groups,omitempty"`
}

// FindAntiAffinityGroup attempts to find an AntiAffinityGroup by nameOrID.
func (l ListAntiAffinityGroupsResponse) FindAntiAffinityGroup(nameOrID string) (AntiAffinityGroup, error) {
	var result []AntiAffinityGroup
	for i, elem := range l.AntiAffinityGroups {
		if string(elem.Name) == nameOrID || string(elem.ID) == nameOrID {
			result = append(result, l.AntiAffinityGroups[i])
		}
	}
	if len(result) == 1 {
		return result[0], nil
	}

	if len(result) > 1 {
		return AntiAffinityGroup{}, fmt.Errorf("%q too many found in ListAntiAffinityGroupsResponse: %w", nameOrID, ErrConflict)
	}

	return AntiAffinityGroup{}, fmt.Errorf("%q not found in ListAntiAffinityGroupsResponse: %w", nameOrID, ErrNotFound)
}

// List Anti-affinity Groups
func (c Client) ListAntiAffinityGroups(ctx context.Context) (*ListAntiAffinityGroupsResponse, error) {
	path := "/anti-affinity-group"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListAntiAffinityGroups: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListAntiAffinityGroups: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListAntiAffinityGroups: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-anti-affinity-groups")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListAntiAffinityGroups: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListAntiAffinityGroups: http response: %w", err)
	}

	bodyresp := new(ListAntiAffinityGroupsResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListAntiAffinityGroups: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type CreateAntiAffinityGroupRequest struct {
	// Anti-affinity Group description
	Description string `json:"description,omitempty" validate:"omitempty,lte=255"`
	// Anti-affinity Group name
	Name string `json:"name" validate:"required,gte=1,lte=255"`
}

// Create an Anti-affinity Group
func (c Client) CreateAntiAffinityGroup(ctx context.Context, req CreateAntiAffinityGroupRequest) (*Operation, error) {
	path := "/anti-affinity-group"

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateAntiAffinityGroup: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateAntiAffinityGroup: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateAntiAffinityGroup: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateAntiAffinityGroup: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-anti-affinity-group")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateAntiAffinityGroup: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateAntiAffinityGroup: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateAntiAffinityGroup: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Delete an Anti-affinity Group
func (c Client) DeleteAntiAffinityGroup(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/anti-affinity-group/%v", id)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteAntiAffinityGroup: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteAntiAffinityGroup: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteAntiAffinityGroup: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-anti-affinity-group")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteAntiAffinityGroup: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteAntiAffinityGroup: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteAntiAffinityGroup: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Retrieve Anti-affinity Group details
func (c Client) GetAntiAffinityGroup(ctx context.Context, id UUID) (*AntiAffinityGroup, error) {
	path := fmt.Sprintf("/anti-affinity-group/%v", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetAntiAffinityGroup: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetAntiAffinityGroup: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetAntiAffinityGroup: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-anti-affinity-group")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetAntiAffinityGroup: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetAntiAffinityGroup: http response: %w", err)
	}

	bodyresp := new(AntiAffinityGroup)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetAntiAffinityGroup: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ListAPIKeysResponse struct {
	APIKeys []IAMAPIKey `json:"api-keys,omitempty"`
}

// FindIAMAPIKey attempts to find an IAMAPIKey by nameOrKey.
func (l ListAPIKeysResponse) FindIAMAPIKey(nameOrKey string) (IAMAPIKey, error) {
	var result []IAMAPIKey
	for i, elem := range l.APIKeys {
		if string(elem.Name) == nameOrKey || string(elem.Key) == nameOrKey {
			result = append(result, l.APIKeys[i])
		}
	}
	if len(result) == 1 {
		return result[0], nil
	}

	if len(result) > 1 {
		return IAMAPIKey{}, fmt.Errorf("%q too many found in ListAPIKeysResponse: %w", nameOrKey, ErrConflict)
	}

	return IAMAPIKey{}, fmt.Errorf("%q not found in ListAPIKeysResponse: %w", nameOrKey, ErrNotFound)
}

func (c Client) ListAPIKeys(ctx context.Context) (*ListAPIKeysResponse, error) {
	path := "/api-key"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListAPIKeys: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListAPIKeys: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListAPIKeys: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-api-keys")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListAPIKeys: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListAPIKeys: http response: %w", err)
	}

	bodyresp := new(ListAPIKeysResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListAPIKeys: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type CreateAPIKeyRequest struct {
	// IAM API Key Name
	Name string `json:"name" validate:"required,gte=1,lte=255"`
	// IAM API Key Role ID
	RoleID UUID `json:"role-id" validate:"required"`
}

func (c Client) CreateAPIKey(ctx context.Context, req CreateAPIKeyRequest) (*IAMAPIKeyCreated, error) {
	path := "/api-key"

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateAPIKey: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateAPIKey: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateAPIKey: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateAPIKey: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-api-key")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateAPIKey: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateAPIKey: http response: %w", err)
	}

	bodyresp := new(IAMAPIKeyCreated)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateAPIKey: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) DeleteAPIKey(ctx context.Context, id string) (*Operation, error) {
	path := fmt.Sprintf("/api-key/%v", id)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteAPIKey: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteAPIKey: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteAPIKey: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-api-key")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteAPIKey: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteAPIKey: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteAPIKey: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) GetAPIKey(ctx context.Context, id string) (*IAMAPIKey, error) {
	path := fmt.Sprintf("/api-key/%v", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetAPIKey: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetAPIKey: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetAPIKey: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-api-key")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetAPIKey: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetAPIKey: http response: %w", err)
	}

	bodyresp := new(IAMAPIKey)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetAPIKey: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ListBlockStorageVolumesResponse struct {
	BlockStorageVolumes []BlockStorageVolume `json:"block-storage-volumes,omitempty"`
}

// FindBlockStorageVolume attempts to find an BlockStorageVolume by nameOrID.
func (l ListBlockStorageVolumesResponse) FindBlockStorageVolume(nameOrID string) (BlockStorageVolume, error) {
	var result []BlockStorageVolume
	for i, elem := range l.BlockStorageVolumes {
		if string(elem.Name) == nameOrID || string(elem.ID) == nameOrID {
			result = append(result, l.BlockStorageVolumes[i])
		}
	}
	if len(result) == 1 {
		return result[0], nil
	}

	if len(result) > 1 {
		return BlockStorageVolume{}, fmt.Errorf("%q too many found in ListBlockStorageVolumesResponse: %w", nameOrID, ErrConflict)
	}

	return BlockStorageVolume{}, fmt.Errorf("%q not found in ListBlockStorageVolumesResponse: %w", nameOrID, ErrNotFound)
}

type ListBlockStorageVolumesOpt func(url.Values)

func ListBlockStorageVolumesWithInstanceID(instanceID UUID) ListBlockStorageVolumesOpt {
	return func(q url.Values) {
		q.Add("instance-id", fmt.Sprint(instanceID))
	}
}

// List block storage volumes
func (c Client) ListBlockStorageVolumes(ctx context.Context, opts ...ListBlockStorageVolumesOpt) (*ListBlockStorageVolumesResponse, error) {
	path := "/block-storage"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListBlockStorageVolumes: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if len(opts) > 0 {
		q := request.URL.Query()
		for _, opt := range opts {
			opt(q)
		}
		request.URL.RawQuery = q.Encode()
	}

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListBlockStorageVolumes: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListBlockStorageVolumes: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-block-storage-volumes")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListBlockStorageVolumes: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListBlockStorageVolumes: http response: %w", err)
	}

	bodyresp := new(ListBlockStorageVolumesResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListBlockStorageVolumes: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type CreateBlockStorageVolumeRequest struct {
	// Target block storage snapshot
	BlockStorageSnapshot *BlockStorageSnapshotTarget `json:"block-storage-snapshot,omitempty"`
	Labels               Labels                      `json:"labels,omitempty"`
	// Volume name
	Name string `json:"name,omitempty" validate:"omitempty,lte=255"`
	// Volume size in GiB.
	// When a snapshot ID is supplied, this defaults to the size of the source volume, but can be set to a larger value.
	Size int64 `json:"size,omitempty" validate:"omitempty,gte=1"`
}

// Create a block storage volume
func (c Client) CreateBlockStorageVolume(ctx context.Context, req CreateBlockStorageVolumeRequest) (*Operation, error) {
	path := "/block-storage"

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateBlockStorageVolume: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateBlockStorageVolume: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateBlockStorageVolume: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateBlockStorageVolume: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-block-storage-volume")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateBlockStorageVolume: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateBlockStorageVolume: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateBlockStorageVolume: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ListBlockStorageSnapshotsResponse struct {
	BlockStorageSnapshots []BlockStorageSnapshot `json:"block-storage-snapshots,omitempty"`
}

// FindBlockStorageSnapshot attempts to find an BlockStorageSnapshot by nameOrID.
func (l ListBlockStorageSnapshotsResponse) FindBlockStorageSnapshot(nameOrID string) (BlockStorageSnapshot, error) {
	var result []BlockStorageSnapshot
	for i, elem := range l.BlockStorageSnapshots {
		if string(elem.Name) == nameOrID || string(elem.ID) == nameOrID {
			result = append(result, l.BlockStorageSnapshots[i])
		}
	}
	if len(result) == 1 {
		return result[0], nil
	}

	if len(result) > 1 {
		return BlockStorageSnapshot{}, fmt.Errorf("%q too many found in ListBlockStorageSnapshotsResponse: %w", nameOrID, ErrConflict)
	}

	return BlockStorageSnapshot{}, fmt.Errorf("%q not found in ListBlockStorageSnapshotsResponse: %w", nameOrID, ErrNotFound)
}

// List block storage snapshots
func (c Client) ListBlockStorageSnapshots(ctx context.Context) (*ListBlockStorageSnapshotsResponse, error) {
	path := "/block-storage-snapshot"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListBlockStorageSnapshots: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListBlockStorageSnapshots: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListBlockStorageSnapshots: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-block-storage-snapshots")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListBlockStorageSnapshots: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListBlockStorageSnapshots: http response: %w", err)
	}

	bodyresp := new(ListBlockStorageSnapshotsResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListBlockStorageSnapshots: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Delete a block storage snapshot, data will be unrecoverable
func (c Client) DeleteBlockStorageSnapshot(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/block-storage-snapshot/%v", id)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteBlockStorageSnapshot: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteBlockStorageSnapshot: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteBlockStorageSnapshot: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-block-storage-snapshot")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteBlockStorageSnapshot: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteBlockStorageSnapshot: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteBlockStorageSnapshot: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Retrieve block storage snapshot details
func (c Client) GetBlockStorageSnapshot(ctx context.Context, id UUID) (*BlockStorageSnapshot, error) {
	path := fmt.Sprintf("/block-storage-snapshot/%v", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetBlockStorageSnapshot: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetBlockStorageSnapshot: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetBlockStorageSnapshot: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-block-storage-snapshot")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetBlockStorageSnapshot: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetBlockStorageSnapshot: http response: %w", err)
	}

	bodyresp := new(BlockStorageSnapshot)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetBlockStorageSnapshot: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type UpdateBlockStorageSnapshotRequest struct {
	Labels Labels `json:"labels"`
	// Snapshot name
	Name *string `json:"name,omitempty" validate:"omitempty,lte=255"`
}

// Update block storage volume snapshot
func (c Client) UpdateBlockStorageSnapshot(ctx context.Context, id UUID, req UpdateBlockStorageSnapshotRequest) (*Operation, error) {
	path := fmt.Sprintf("/block-storage-snapshot/%v", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateBlockStorageSnapshot: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateBlockStorageSnapshot: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateBlockStorageSnapshot: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateBlockStorageSnapshot: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-block-storage-snapshot")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateBlockStorageSnapshot: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateBlockStorageSnapshot: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateBlockStorageSnapshot: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Delete a block storage volume, data will be unrecoverable
func (c Client) DeleteBlockStorageVolume(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/block-storage/%v", id)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteBlockStorageVolume: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteBlockStorageVolume: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteBlockStorageVolume: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-block-storage-volume")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteBlockStorageVolume: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteBlockStorageVolume: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteBlockStorageVolume: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Retrieve block storage volume details
func (c Client) GetBlockStorageVolume(ctx context.Context, id UUID) (*BlockStorageVolume, error) {
	path := fmt.Sprintf("/block-storage/%v", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetBlockStorageVolume: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetBlockStorageVolume: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetBlockStorageVolume: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-block-storage-volume")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetBlockStorageVolume: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetBlockStorageVolume: http response: %w", err)
	}

	bodyresp := new(BlockStorageVolume)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetBlockStorageVolume: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type UpdateBlockStorageVolumeRequest struct {
	Labels Labels `json:"labels"`
	// Volume name
	Name *string `json:"name,omitempty" validate:"omitempty,lte=255"`
}

// Update block storage volume
func (c Client) UpdateBlockStorageVolume(ctx context.Context, id UUID, req UpdateBlockStorageVolumeRequest) (*Operation, error) {
	path := fmt.Sprintf("/block-storage/%v", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateBlockStorageVolume: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateBlockStorageVolume: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateBlockStorageVolume: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateBlockStorageVolume: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-block-storage-volume")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateBlockStorageVolume: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateBlockStorageVolume: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateBlockStorageVolume: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type AttachBlockStorageVolumeToInstanceRequest struct {
	// Target Instance
	Instance *InstanceTarget `json:"instance" validate:"required"`
}

// Attach block storage volume to an instance
func (c Client) AttachBlockStorageVolumeToInstance(ctx context.Context, id UUID, req AttachBlockStorageVolumeToInstanceRequest) (*Operation, error) {
	path := fmt.Sprintf("/block-storage/%v:attach", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("AttachBlockStorageVolumeToInstance: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("AttachBlockStorageVolumeToInstance: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("AttachBlockStorageVolumeToInstance: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("AttachBlockStorageVolumeToInstance: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "attach-block-storage-volume-to-instance")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("AttachBlockStorageVolumeToInstance: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("AttachBlockStorageVolumeToInstance: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("AttachBlockStorageVolumeToInstance: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type CreateBlockStorageSnapshotRequest struct {
	Labels Labels `json:"labels,omitempty"`
	// Snapshot name
	Name string `json:"name,omitempty" validate:"omitempty,gte=1,lte=255"`
}

// Create a block storage snapshot
func (c Client) CreateBlockStorageSnapshot(ctx context.Context, id UUID, req CreateBlockStorageSnapshotRequest) (*Operation, error) {
	path := fmt.Sprintf("/block-storage/%v:create-snapshot", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateBlockStorageSnapshot: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateBlockStorageSnapshot: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateBlockStorageSnapshot: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateBlockStorageSnapshot: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-block-storage-snapshot")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateBlockStorageSnapshot: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateBlockStorageSnapshot: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateBlockStorageSnapshot: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Detach block storage volume
func (c Client) DetachBlockStorageVolume(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/block-storage/%v:detach", id)

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DetachBlockStorageVolume: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DetachBlockStorageVolume: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DetachBlockStorageVolume: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "detach-block-storage-volume")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DetachBlockStorageVolume: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DetachBlockStorageVolume: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DetachBlockStorageVolume: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ResizeBlockStorageVolumeRequest struct {
	// Volume size in GiB
	Size int64 `json:"size" validate:"required,gt=0"`
}

// This operation resizes a Block storage volume. Note: the volume can only grow, cannot be shrunk. Only detached volumes or volumes attached to stopped instances can be resized.
func (c Client) ResizeBlockStorageVolume(ctx context.Context, id UUID, req ResizeBlockStorageVolumeRequest) (*BlockStorageVolume, error) {
	path := fmt.Sprintf("/block-storage/%v:resize-volume", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("ResizeBlockStorageVolume: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("ResizeBlockStorageVolume: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ResizeBlockStorageVolume: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ResizeBlockStorageVolume: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "resize-block-storage-volume")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ResizeBlockStorageVolume: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ResizeBlockStorageVolume: http response: %w", err)
	}

	bodyresp := new(BlockStorageVolume)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ResizeBlockStorageVolume: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type GetConsoleProxyURLResponse struct {
	Host string `json:"host,omitempty"`
	Path string `json:"path,omitempty"`
	URL  string `json:"url,omitempty"`
}

// Retrieve signed url valid for 60 seconds to connect via console-proxy websocket to VM VNC console.
func (c Client) GetConsoleProxyURL(ctx context.Context, id UUID) (*GetConsoleProxyURLResponse, error) {
	path := fmt.Sprintf("/console/%v", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetConsoleProxyURL: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetConsoleProxyURL: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetConsoleProxyURL: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-console-proxy-url")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetConsoleProxyURL: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetConsoleProxyURL: http response: %w", err)
	}

	bodyresp := new(GetConsoleProxyURLResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetConsoleProxyURL: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type GetDBAASCACertificateResponse struct {
	Certificate string `json:"certificate,omitempty"`
}

// Returns a CA Certificate required to reach a DBaaS service through a TLS-protected connection.
func (c Client) GetDBAASCACertificate(ctx context.Context) (*GetDBAASCACertificateResponse, error) {
	path := "/dbaas-ca-certificate"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASCACertificate: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASCACertificate: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASCACertificate: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-ca-certificate")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASCACertificate: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASCACertificate: http response: %w", err)
	}

	bodyresp := new(GetDBAASCACertificateResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASCACertificate: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) DeleteDBAASServiceClickhouse(ctx context.Context, name string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-clickhouse/%v", name)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceClickhouse: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceClickhouse: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceClickhouse: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-dbaas-service-clickhouse")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceClickhouse: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceClickhouse: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceClickhouse: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) GetDBAASServiceClickhouse(ctx context.Context, name string) (*DBAASServiceClickhouse, error) {
	path := fmt.Sprintf("/dbaas-clickhouse/%v", name)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASServiceClickhouse: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceClickhouse: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceClickhouse: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-service-clickhouse")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASServiceClickhouse: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceClickhouse: http response: %w", err)
	}

	bodyresp := new(DBAASServiceClickhouse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceClickhouse: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type CreateDBAASServiceClickhouseRequestMaintenanceDow string

const (
	CreateDBAASServiceClickhouseRequestMaintenanceDowSaturday  CreateDBAASServiceClickhouseRequestMaintenanceDow = "saturday"
	CreateDBAASServiceClickhouseRequestMaintenanceDowTuesday   CreateDBAASServiceClickhouseRequestMaintenanceDow = "tuesday"
	CreateDBAASServiceClickhouseRequestMaintenanceDowNever     CreateDBAASServiceClickhouseRequestMaintenanceDow = "never"
	CreateDBAASServiceClickhouseRequestMaintenanceDowWednesday CreateDBAASServiceClickhouseRequestMaintenanceDow = "wednesday"
	CreateDBAASServiceClickhouseRequestMaintenanceDowSunday    CreateDBAASServiceClickhouseRequestMaintenanceDow = "sunday"
	CreateDBAASServiceClickhouseRequestMaintenanceDowFriday    CreateDBAASServiceClickhouseRequestMaintenanceDow = "friday"
	CreateDBAASServiceClickhouseRequestMaintenanceDowMonday    CreateDBAASServiceClickhouseRequestMaintenanceDow = "monday"
	CreateDBAASServiceClickhouseRequestMaintenanceDowThursday  CreateDBAASServiceClickhouseRequestMaintenanceDow = "thursday"
)

// Automatic maintenance settings
type CreateDBAASServiceClickhouseRequestMaintenance struct {
	// Day of week for installing updates
	Dow CreateDBAASServiceClickhouseRequestMaintenanceDow `json:"dow" validate:"required"`
	// Time for installing updates, UTC
	Time string `json:"time" validate:"required,gte=8,lte=8"`
}

type CreateDBAASServiceClickhouseRequest struct {
	// ClickHouse settings
	ClickhouseSettings *JSONSchemaClickhouse `json:"clickhouse-settings,omitempty"`
	ForkFromService    DBAASServiceName      `json:"fork-from-service,omitempty" validate:"omitempty,gte=0,lte=63"`
	// Allow incoming connections from CIDR address block, e.g. '10.20.0.0/16'
	IPFilter []string `json:"ip-filter,omitempty"`
	// Automatic maintenance settings
	Maintenance *CreateDBAASServiceClickhouseRequestMaintenance `json:"maintenance,omitempty"`
	// Subscription plan
	Plan string `json:"plan" validate:"required,gte=1,lte=128"`
	// Name of a backup to recover from for services that support backup names
	RecoveryBackupName string `json:"recovery-backup-name,omitempty" validate:"omitempty,gte=1"`
	// Service is protected against termination and powering off
	TerminationProtection *bool `json:"termination-protection,omitempty"`
	// ClickHouse major version
	Version string `json:"version,omitempty" validate:"omitempty,gte=1"`
}

func (c Client) CreateDBAASServiceClickhouse(ctx context.Context, name string, req CreateDBAASServiceClickhouseRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-clickhouse/%v", name)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceClickhouse: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceClickhouse: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceClickhouse: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceClickhouse: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-dbaas-service-clickhouse")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceClickhouse: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceClickhouse: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceClickhouse: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type UpdateDBAASServiceClickhouseRequestMaintenanceDow string

const (
	UpdateDBAASServiceClickhouseRequestMaintenanceDowSaturday  UpdateDBAASServiceClickhouseRequestMaintenanceDow = "saturday"
	UpdateDBAASServiceClickhouseRequestMaintenanceDowTuesday   UpdateDBAASServiceClickhouseRequestMaintenanceDow = "tuesday"
	UpdateDBAASServiceClickhouseRequestMaintenanceDowNever     UpdateDBAASServiceClickhouseRequestMaintenanceDow = "never"
	UpdateDBAASServiceClickhouseRequestMaintenanceDowWednesday UpdateDBAASServiceClickhouseRequestMaintenanceDow = "wednesday"
	UpdateDBAASServiceClickhouseRequestMaintenanceDowSunday    UpdateDBAASServiceClickhouseRequestMaintenanceDow = "sunday"
	UpdateDBAASServiceClickhouseRequestMaintenanceDowFriday    UpdateDBAASServiceClickhouseRequestMaintenanceDow = "friday"
	UpdateDBAASServiceClickhouseRequestMaintenanceDowMonday    UpdateDBAASServiceClickhouseRequestMaintenanceDow = "monday"
	UpdateDBAASServiceClickhouseRequestMaintenanceDowThursday  UpdateDBAASServiceClickhouseRequestMaintenanceDow = "thursday"
)

// Automatic maintenance settings
type UpdateDBAASServiceClickhouseRequestMaintenance struct {
	// Day of week for installing updates
	Dow UpdateDBAASServiceClickhouseRequestMaintenanceDow `json:"dow" validate:"required"`
	// Time for installing updates, UTC
	Time string `json:"time" validate:"required,gte=8,lte=8"`
}

type UpdateDBAASServiceClickhouseRequest struct {
	// ClickHouse settings
	ClickhouseSettings *JSONSchemaClickhouse `json:"clickhouse-settings,omitempty"`
	// Allow incoming connections from CIDR address block, e.g. '10.20.0.0/16'
	IPFilter []string `json:"ip-filter,omitempty"`
	// Automatic maintenance settings
	Maintenance *UpdateDBAASServiceClickhouseRequestMaintenance `json:"maintenance,omitempty"`
	// Subscription plan
	Plan string `json:"plan,omitempty" validate:"omitempty,gte=1,lte=128"`
	// Service is protected against termination and powering off
	TerminationProtection *bool `json:"termination-protection,omitempty"`
	// ClickHouse major version
	Version string `json:"version,omitempty" validate:"omitempty,gte=1"`
}

func (c Client) UpdateDBAASServiceClickhouse(ctx context.Context, name string, req UpdateDBAASServiceClickhouseRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-clickhouse/%v", name)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceClickhouse: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceClickhouse: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceClickhouse: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceClickhouse: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-dbaas-service-clickhouse")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceClickhouse: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceClickhouse: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceClickhouse: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) StartDBAASClickhouseMaintenance(ctx context.Context, name string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-clickhouse/%v/maintenance/start", name)

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("StartDBAASClickhouseMaintenance: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("StartDBAASClickhouseMaintenance: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("StartDBAASClickhouseMaintenance: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "start-dbaas-clickhouse-maintenance")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("StartDBAASClickhouseMaintenance: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("StartDBAASClickhouseMaintenance: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("StartDBAASClickhouseMaintenance: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) GetDBAASClickhouseAclConfig(ctx context.Context, serviceName string) (*DBAASClickhouseAclConfig, error) {
	path := fmt.Sprintf("/dbaas-clickhouse/%v/acl-config", serviceName)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASClickhouseAclConfig: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASClickhouseAclConfig: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASClickhouseAclConfig: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-clickhouse-acl-config")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASClickhouseAclConfig: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASClickhouseAclConfig: http response: %w", err)
	}

	bodyresp := new(DBAASClickhouseAclConfig)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASClickhouseAclConfig: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) ListDBAASClickhouseUsers(ctx context.Context, serviceName string) (*DBAASClickhouseUsers, error) {
	path := fmt.Sprintf("/dbaas-clickhouse/%v/user", serviceName)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListDBAASClickhouseUsers: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListDBAASClickhouseUsers: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListDBAASClickhouseUsers: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-dbaas-clickhouse-users")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListDBAASClickhouseUsers: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListDBAASClickhouseUsers: http response: %w", err)
	}

	bodyresp := new(DBAASClickhouseUsers)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListDBAASClickhouseUsers: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type CreateDBAASClickhouseUserRequest struct {
	Password DBAASUserPassword `json:"password,omitempty" validate:"omitempty,gte=8,lte=256"`
	// ClickHouse roles to grant to the user
	Roles    []DBAASClickhouseUserRoleInput `json:"roles,omitempty"`
	Username DBAASUserUsername              `json:"username" validate:"required,gte=1,lte=64"`
}

func (c Client) CreateDBAASClickhouseUser(ctx context.Context, serviceName string, req CreateDBAASClickhouseUserRequest) (*DBAASUserClickhouseSecrets, error) {
	path := fmt.Sprintf("/dbaas-clickhouse/%v/user", serviceName)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASClickhouseUser: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASClickhouseUser: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateDBAASClickhouseUser: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateDBAASClickhouseUser: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-dbaas-clickhouse-user")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASClickhouseUser: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateDBAASClickhouseUser: http response: %w", err)
	}

	bodyresp := new(DBAASUserClickhouseSecrets)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateDBAASClickhouseUser: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) DeleteDBAASClickhouseUser(ctx context.Context, serviceName string, username string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-clickhouse/%v/user/%v", serviceName, username)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASClickhouseUser: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASClickhouseUser: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASClickhouseUser: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-dbaas-clickhouse-user")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASClickhouseUser: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteDBAASClickhouseUser: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteDBAASClickhouseUser: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ResetDBAASClickhouseUserPasswordRequest struct {
	Password DBAASUserPassword `json:"password,omitempty" validate:"omitempty,gte=8,lte=256"`
}

func (c Client) ResetDBAASClickhouseUserPassword(ctx context.Context, serviceName string, username string, req ResetDBAASClickhouseUserPasswordRequest) (*DBAASUserClickhouseSecrets, error) {
	path := fmt.Sprintf("/dbaas-clickhouse/%v/user/%v/password/reset", serviceName, username)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("ResetDBAASClickhouseUserPassword: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("ResetDBAASClickhouseUserPassword: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ResetDBAASClickhouseUserPassword: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ResetDBAASClickhouseUserPassword: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reset-dbaas-clickhouse-user-password")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ResetDBAASClickhouseUserPassword: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ResetDBAASClickhouseUserPassword: http response: %w", err)
	}

	bodyresp := new(DBAASUserClickhouseSecrets)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ResetDBAASClickhouseUserPassword: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) RevealDBAASClickhouseUserPassword(ctx context.Context, serviceName string, username string) (*DBAASUserClickhouseSecrets, error) {
	path := fmt.Sprintf("/dbaas-clickhouse/%v/user/%v/password/reveal", serviceName, username)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("RevealDBAASClickhouseUserPassword: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("RevealDBAASClickhouseUserPassword: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("RevealDBAASClickhouseUserPassword: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reveal-dbaas-clickhouse-user-password")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("RevealDBAASClickhouseUserPassword: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("RevealDBAASClickhouseUserPassword: http response: %w", err)
	}

	bodyresp := new(DBAASUserClickhouseSecrets)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("RevealDBAASClickhouseUserPassword: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// [BETA] Delete DataDog external integration endpoint
func (c Client) DeleteDBAASExternalEndpointDatadog(ctx context.Context, endpointID UUID) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-external-endpoint-datadog/%v", endpointID)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASExternalEndpointDatadog: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASExternalEndpointDatadog: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASExternalEndpointDatadog: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-dbaas-external-endpoint-datadog")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASExternalEndpointDatadog: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteDBAASExternalEndpointDatadog: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteDBAASExternalEndpointDatadog: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// [BETA] Get DataDog external endpoint settings
func (c Client) GetDBAASExternalEndpointDatadog(ctx context.Context, endpointID UUID) (*DBAASExternalEndpointDatadogOutput, error) {
	path := fmt.Sprintf("/dbaas-external-endpoint-datadog/%v", endpointID)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASExternalEndpointDatadog: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASExternalEndpointDatadog: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASExternalEndpointDatadog: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-external-endpoint-datadog")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASExternalEndpointDatadog: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASExternalEndpointDatadog: http response: %w", err)
	}

	bodyresp := new(DBAASExternalEndpointDatadogOutput)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASExternalEndpointDatadog: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// [BETA] Update DataDog external integration endpoint
func (c Client) UpdateDBAASExternalEndpointDatadog(ctx context.Context, endpointID UUID, req DBAASEndpointDatadogInputUpdate) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-external-endpoint-datadog/%v", endpointID)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASExternalEndpointDatadog: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASExternalEndpointDatadog: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASExternalEndpointDatadog: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASExternalEndpointDatadog: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-dbaas-external-endpoint-datadog")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASExternalEndpointDatadog: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateDBAASExternalEndpointDatadog: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateDBAASExternalEndpointDatadog: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// [BETA] Create DataDog external integration endpoint
func (c Client) CreateDBAASExternalEndpointDatadog(ctx context.Context, name string, req DBAASEndpointDatadogInputCreate) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-external-endpoint-datadog/%v", name)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASExternalEndpointDatadog: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASExternalEndpointDatadog: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateDBAASExternalEndpointDatadog: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateDBAASExternalEndpointDatadog: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-dbaas-external-endpoint-datadog")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASExternalEndpointDatadog: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateDBAASExternalEndpointDatadog: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateDBAASExternalEndpointDatadog: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// [BETA] Delete ElasticSearch logs external integration endpoint
func (c Client) DeleteDBAASExternalEndpointElasticsearch(ctx context.Context, endpointID UUID) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-external-endpoint-elasticsearch/%v", endpointID)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASExternalEndpointElasticsearch: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASExternalEndpointElasticsearch: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASExternalEndpointElasticsearch: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-dbaas-external-endpoint-elasticsearch")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASExternalEndpointElasticsearch: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteDBAASExternalEndpointElasticsearch: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteDBAASExternalEndpointElasticsearch: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// [BETA] Get ElasticSearch Logs external integration endpoint settings
func (c Client) GetDBAASExternalEndpointElasticsearch(ctx context.Context, endpointID UUID) (*DBAASEndpointElasticsearchOutput, error) {
	path := fmt.Sprintf("/dbaas-external-endpoint-elasticsearch/%v", endpointID)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASExternalEndpointElasticsearch: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASExternalEndpointElasticsearch: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASExternalEndpointElasticsearch: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-external-endpoint-elasticsearch")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASExternalEndpointElasticsearch: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASExternalEndpointElasticsearch: http response: %w", err)
	}

	bodyresp := new(DBAASEndpointElasticsearchOutput)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASExternalEndpointElasticsearch: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// [BETA] Update ElasticSearch Logs external integration endpoint
func (c Client) UpdateDBAASExternalEndpointElasticsearch(ctx context.Context, endpointID UUID, req DBAASEndpointElasticsearchInputUpdate) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-external-endpoint-elasticsearch/%v", endpointID)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASExternalEndpointElasticsearch: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASExternalEndpointElasticsearch: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASExternalEndpointElasticsearch: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASExternalEndpointElasticsearch: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-dbaas-external-endpoint-elasticsearch")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASExternalEndpointElasticsearch: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateDBAASExternalEndpointElasticsearch: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateDBAASExternalEndpointElasticsearch: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// [BETA] Create ElasticSearch Logs external integration endpoint
func (c Client) CreateDBAASExternalEndpointElasticsearch(ctx context.Context, name string, req DBAASEndpointElasticsearchInputCreate) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-external-endpoint-elasticsearch/%v", name)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASExternalEndpointElasticsearch: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASExternalEndpointElasticsearch: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateDBAASExternalEndpointElasticsearch: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateDBAASExternalEndpointElasticsearch: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-dbaas-external-endpoint-elasticsearch")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASExternalEndpointElasticsearch: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateDBAASExternalEndpointElasticsearch: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateDBAASExternalEndpointElasticsearch: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// [BETA] Delete OpenSearch logs external integration endpoint
func (c Client) DeleteDBAASExternalEndpointOpensearch(ctx context.Context, endpointID UUID) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-external-endpoint-opensearch/%v", endpointID)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASExternalEndpointOpensearch: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASExternalEndpointOpensearch: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASExternalEndpointOpensearch: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-dbaas-external-endpoint-opensearch")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASExternalEndpointOpensearch: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteDBAASExternalEndpointOpensearch: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteDBAASExternalEndpointOpensearch: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// [BETA] Get OpenSearch Logs external integration endpoint settings
func (c Client) GetDBAASExternalEndpointOpensearch(ctx context.Context, endpointID UUID) (*DBAASEndpointOpensearchOutput, error) {
	path := fmt.Sprintf("/dbaas-external-endpoint-opensearch/%v", endpointID)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASExternalEndpointOpensearch: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASExternalEndpointOpensearch: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASExternalEndpointOpensearch: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-external-endpoint-opensearch")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASExternalEndpointOpensearch: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASExternalEndpointOpensearch: http response: %w", err)
	}

	bodyresp := new(DBAASEndpointOpensearchOutput)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASExternalEndpointOpensearch: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// [BETA] Update OpenSearch Logs external integration endpoint
func (c Client) UpdateDBAASExternalEndpointOpensearch(ctx context.Context, endpointID UUID, req DBAASEndpointOpensearchInputUpdate) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-external-endpoint-opensearch/%v", endpointID)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASExternalEndpointOpensearch: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASExternalEndpointOpensearch: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASExternalEndpointOpensearch: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASExternalEndpointOpensearch: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-dbaas-external-endpoint-opensearch")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASExternalEndpointOpensearch: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateDBAASExternalEndpointOpensearch: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateDBAASExternalEndpointOpensearch: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// [BETA] Create OpenSearch Logs external integration endpoint
func (c Client) CreateDBAASExternalEndpointOpensearch(ctx context.Context, name string, req DBAASEndpointOpensearchInputCreate) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-external-endpoint-opensearch/%v", name)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASExternalEndpointOpensearch: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASExternalEndpointOpensearch: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateDBAASExternalEndpointOpensearch: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateDBAASExternalEndpointOpensearch: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-dbaas-external-endpoint-opensearch")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASExternalEndpointOpensearch: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateDBAASExternalEndpointOpensearch: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateDBAASExternalEndpointOpensearch: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// [BETA] Delete Prometheus external integration endpoint
func (c Client) DeleteDBAASExternalEndpointPrometheus(ctx context.Context, endpointID UUID) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-external-endpoint-prometheus/%v", endpointID)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASExternalEndpointPrometheus: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASExternalEndpointPrometheus: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASExternalEndpointPrometheus: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-dbaas-external-endpoint-prometheus")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASExternalEndpointPrometheus: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteDBAASExternalEndpointPrometheus: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteDBAASExternalEndpointPrometheus: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// [BETA] Get Prometheus external integration endpoint settings
func (c Client) GetDBAASExternalEndpointPrometheus(ctx context.Context, endpointID UUID) (*DBAASEndpointExternalPrometheusOutput, error) {
	path := fmt.Sprintf("/dbaas-external-endpoint-prometheus/%v", endpointID)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASExternalEndpointPrometheus: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASExternalEndpointPrometheus: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASExternalEndpointPrometheus: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-external-endpoint-prometheus")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASExternalEndpointPrometheus: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASExternalEndpointPrometheus: http response: %w", err)
	}

	bodyresp := new(DBAASEndpointExternalPrometheusOutput)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASExternalEndpointPrometheus: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// [BETA] Update Prometheus external integration endpoint
func (c Client) UpdateDBAASExternalEndpointPrometheus(ctx context.Context, endpointID UUID, req DBAASEndpointPrometheusPayload) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-external-endpoint-prometheus/%v", endpointID)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASExternalEndpointPrometheus: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASExternalEndpointPrometheus: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASExternalEndpointPrometheus: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASExternalEndpointPrometheus: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-dbaas-external-endpoint-prometheus")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASExternalEndpointPrometheus: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateDBAASExternalEndpointPrometheus: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateDBAASExternalEndpointPrometheus: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// [BETA] Create Prometheus external integration endpoint
func (c Client) CreateDBAASExternalEndpointPrometheus(ctx context.Context, name string, req DBAASEndpointPrometheusPayload) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-external-endpoint-prometheus/%v", name)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASExternalEndpointPrometheus: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASExternalEndpointPrometheus: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateDBAASExternalEndpointPrometheus: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateDBAASExternalEndpointPrometheus: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-dbaas-external-endpoint-prometheus")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASExternalEndpointPrometheus: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateDBAASExternalEndpointPrometheus: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateDBAASExternalEndpointPrometheus: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// [BETA] Delete RSyslog external integration endpoint
func (c Client) DeleteDBAASExternalEndpointRsyslog(ctx context.Context, endpointID UUID) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-external-endpoint-rsyslog/%v", endpointID)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASExternalEndpointRsyslog: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASExternalEndpointRsyslog: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASExternalEndpointRsyslog: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-dbaas-external-endpoint-rsyslog")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASExternalEndpointRsyslog: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteDBAASExternalEndpointRsyslog: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteDBAASExternalEndpointRsyslog: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// [BETA] Get RSyslog external integration endpoint settings
func (c Client) GetDBAASExternalEndpointRsyslog(ctx context.Context, endpointID UUID) (*DBAASExternalEndpointRsyslogOutput, error) {
	path := fmt.Sprintf("/dbaas-external-endpoint-rsyslog/%v", endpointID)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASExternalEndpointRsyslog: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASExternalEndpointRsyslog: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASExternalEndpointRsyslog: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-external-endpoint-rsyslog")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASExternalEndpointRsyslog: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASExternalEndpointRsyslog: http response: %w", err)
	}

	bodyresp := new(DBAASExternalEndpointRsyslogOutput)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASExternalEndpointRsyslog: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// [BETA] Update RSyslog external integration endpoint
func (c Client) UpdateDBAASExternalEndpointRsyslog(ctx context.Context, endpointID UUID, req DBAASEndpointRsyslogInputUpdate) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-external-endpoint-rsyslog/%v", endpointID)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASExternalEndpointRsyslog: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASExternalEndpointRsyslog: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASExternalEndpointRsyslog: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASExternalEndpointRsyslog: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-dbaas-external-endpoint-rsyslog")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASExternalEndpointRsyslog: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateDBAASExternalEndpointRsyslog: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateDBAASExternalEndpointRsyslog: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// [BETA] Create RSyslog external integration endpoint
func (c Client) CreateDBAASExternalEndpointRsyslog(ctx context.Context, name string, req DBAASEndpointRsyslogInputCreate) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-external-endpoint-rsyslog/%v", name)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASExternalEndpointRsyslog: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASExternalEndpointRsyslog: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateDBAASExternalEndpointRsyslog: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateDBAASExternalEndpointRsyslog: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-dbaas-external-endpoint-rsyslog")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASExternalEndpointRsyslog: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateDBAASExternalEndpointRsyslog: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateDBAASExternalEndpointRsyslog: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ListDBAASExternalEndpointTypesResponseEndpointTypes struct {
	ServiceTypes []string                  `json:"service-types,omitempty"`
	Title        string                    `json:"title,omitempty"`
	Type         EnumExternalEndpointTypes `json:"type,omitempty"`
}

type ListDBAASExternalEndpointTypesResponse struct {
	EndpointTypes []ListDBAASExternalEndpointTypesResponseEndpointTypes `json:"endpoint-types,omitempty"`
}

// [BETA] List available external endpoint types and their schemas for DBaaS external integrations
func (c Client) ListDBAASExternalEndpointTypes(ctx context.Context) (*ListDBAASExternalEndpointTypesResponse, error) {
	path := "/dbaas-external-endpoint-types"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListDBAASExternalEndpointTypes: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListDBAASExternalEndpointTypes: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListDBAASExternalEndpointTypes: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-dbaas-external-endpoint-types")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListDBAASExternalEndpointTypes: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListDBAASExternalEndpointTypes: http response: %w", err)
	}

	bodyresp := new(ListDBAASExternalEndpointTypesResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListDBAASExternalEndpointTypes: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type AttachDBAASServiceToEndpointRequest struct {
	// External endpoint id
	DestEndpointID UUID                      `json:"dest-endpoint-id" validate:"required"`
	Type           EnumExternalEndpointTypes `json:"type" validate:"required"`
}

// [BETA] Create a new DBaaS connection between a DBaaS service and an external service
func (c Client) AttachDBAASServiceToEndpoint(ctx context.Context, sourceServiceName string, req AttachDBAASServiceToEndpointRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-external-endpoint/%v/attach", sourceServiceName)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("AttachDBAASServiceToEndpoint: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("AttachDBAASServiceToEndpoint: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("AttachDBAASServiceToEndpoint: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("AttachDBAASServiceToEndpoint: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "attach-dbaas-service-to-endpoint")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("AttachDBAASServiceToEndpoint: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("AttachDBAASServiceToEndpoint: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("AttachDBAASServiceToEndpoint: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type DetachDBAASServiceFromEndpointRequest struct {
	// External Integration ID
	IntegrationID UUID `json:"integration-id" validate:"required"`
}

// [BETA] Detach a DBaaS external integration from a service
func (c Client) DetachDBAASServiceFromEndpoint(ctx context.Context, sourceServiceName string, req DetachDBAASServiceFromEndpointRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-external-endpoint/%v/detach", sourceServiceName)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("DetachDBAASServiceFromEndpoint: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("DetachDBAASServiceFromEndpoint: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DetachDBAASServiceFromEndpoint: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DetachDBAASServiceFromEndpoint: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "detach-dbaas-service-from-endpoint")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DetachDBAASServiceFromEndpoint: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DetachDBAASServiceFromEndpoint: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DetachDBAASServiceFromEndpoint: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ListDBAASExternalEndpointsResponse struct {
	DBAASEndpoints []DBAASExternalEndpoint `json:"dbaas-endpoints,omitempty"`
}

// FindDBAASExternalEndpoint attempts to find an DBAASExternalEndpoint by nameOrID.
func (l ListDBAASExternalEndpointsResponse) FindDBAASExternalEndpoint(nameOrID string) (DBAASExternalEndpoint, error) {
	var result []DBAASExternalEndpoint
	for i, elem := range l.DBAASEndpoints {
		if string(elem.Name) == nameOrID || string(elem.ID) == nameOrID {
			result = append(result, l.DBAASEndpoints[i])
		}
	}
	if len(result) == 1 {
		return result[0], nil
	}

	if len(result) > 1 {
		return DBAASExternalEndpoint{}, fmt.Errorf("%q too many found in ListDBAASExternalEndpointsResponse: %w", nameOrID, ErrConflict)
	}

	return DBAASExternalEndpoint{}, fmt.Errorf("%q not found in ListDBAASExternalEndpointsResponse: %w", nameOrID, ErrNotFound)
}

// [BETA] List available external endpoints for integrations
func (c Client) ListDBAASExternalEndpoints(ctx context.Context) (*ListDBAASExternalEndpointsResponse, error) {
	path := "/dbaas-external-endpoints"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListDBAASExternalEndpoints: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListDBAASExternalEndpoints: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListDBAASExternalEndpoints: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-dbaas-external-endpoints")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListDBAASExternalEndpoints: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListDBAASExternalEndpoints: http response: %w", err)
	}

	bodyresp := new(ListDBAASExternalEndpointsResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListDBAASExternalEndpoints: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type GetDBAASExternalIntegrationSettingsDatadogResponse struct {
	Settings *DBAASIntegrationSettingsDatadog `json:"settings,omitempty"`
}

// [BETA] Get Datadog integration settings
func (c Client) GetDBAASExternalIntegrationSettingsDatadog(ctx context.Context, integrationID UUID) (*GetDBAASExternalIntegrationSettingsDatadogResponse, error) {
	path := fmt.Sprintf("/dbaas-external-integration-settings-datadog/%v", integrationID)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASExternalIntegrationSettingsDatadog: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASExternalIntegrationSettingsDatadog: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASExternalIntegrationSettingsDatadog: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-external-integration-settings-datadog")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASExternalIntegrationSettingsDatadog: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASExternalIntegrationSettingsDatadog: http response: %w", err)
	}

	bodyresp := new(GetDBAASExternalIntegrationSettingsDatadogResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASExternalIntegrationSettingsDatadog: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type UpdateDBAASExternalIntegrationSettingsDatadogRequest struct {
	Settings *DBAASIntegrationSettingsDatadog `json:"settings,omitempty"`
}

// [BETA] Manage Datadog integration settings
func (c Client) UpdateDBAASExternalIntegrationSettingsDatadog(ctx context.Context, integrationID UUID, req UpdateDBAASExternalIntegrationSettingsDatadogRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-external-integration-settings-datadog/%v", integrationID)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASExternalIntegrationSettingsDatadog: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASExternalIntegrationSettingsDatadog: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASExternalIntegrationSettingsDatadog: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASExternalIntegrationSettingsDatadog: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-dbaas-external-integration-settings-datadog")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASExternalIntegrationSettingsDatadog: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateDBAASExternalIntegrationSettingsDatadog: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateDBAASExternalIntegrationSettingsDatadog: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// [BETA] Get a DBaaS external integration
func (c Client) GetDBAASExternalIntegration(ctx context.Context, integrationID UUID) (*DBAASExternalIntegration, error) {
	path := fmt.Sprintf("/dbaas-external-integration/%v", integrationID)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASExternalIntegration: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASExternalIntegration: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASExternalIntegration: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-external-integration")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASExternalIntegration: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASExternalIntegration: http response: %w", err)
	}

	bodyresp := new(DBAASExternalIntegration)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASExternalIntegration: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ListDBAASExternalIntegrationsResponse struct {
	ExternalIntegrations []DBAASExternalIntegration `json:"external-integrations,omitempty"`
}

// [BETA] List all DBaaS connections between services and external endpoints
func (c Client) ListDBAASExternalIntegrations(ctx context.Context, serviceName string) (*ListDBAASExternalIntegrationsResponse, error) {
	path := fmt.Sprintf("/dbaas-external-integrations/%v", serviceName)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListDBAASExternalIntegrations: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListDBAASExternalIntegrations: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListDBAASExternalIntegrations: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-dbaas-external-integrations")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListDBAASExternalIntegrations: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListDBAASExternalIntegrations: http response: %w", err)
	}

	bodyresp := new(ListDBAASExternalIntegrationsResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListDBAASExternalIntegrations: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) DeleteDBAASServiceGrafana(ctx context.Context, name string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-grafana/%v", name)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceGrafana: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceGrafana: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceGrafana: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-dbaas-service-grafana")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceGrafana: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceGrafana: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceGrafana: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) GetDBAASServiceGrafana(ctx context.Context, name string) (*DBAASServiceGrafana, error) {
	path := fmt.Sprintf("/dbaas-grafana/%v", name)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASServiceGrafana: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceGrafana: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceGrafana: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-service-grafana")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASServiceGrafana: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceGrafana: http response: %w", err)
	}

	bodyresp := new(DBAASServiceGrafana)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceGrafana: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type CreateDBAASServiceGrafanaRequestMaintenanceDow string

const (
	CreateDBAASServiceGrafanaRequestMaintenanceDowSaturday  CreateDBAASServiceGrafanaRequestMaintenanceDow = "saturday"
	CreateDBAASServiceGrafanaRequestMaintenanceDowTuesday   CreateDBAASServiceGrafanaRequestMaintenanceDow = "tuesday"
	CreateDBAASServiceGrafanaRequestMaintenanceDowNever     CreateDBAASServiceGrafanaRequestMaintenanceDow = "never"
	CreateDBAASServiceGrafanaRequestMaintenanceDowWednesday CreateDBAASServiceGrafanaRequestMaintenanceDow = "wednesday"
	CreateDBAASServiceGrafanaRequestMaintenanceDowSunday    CreateDBAASServiceGrafanaRequestMaintenanceDow = "sunday"
	CreateDBAASServiceGrafanaRequestMaintenanceDowFriday    CreateDBAASServiceGrafanaRequestMaintenanceDow = "friday"
	CreateDBAASServiceGrafanaRequestMaintenanceDowMonday    CreateDBAASServiceGrafanaRequestMaintenanceDow = "monday"
	CreateDBAASServiceGrafanaRequestMaintenanceDowThursday  CreateDBAASServiceGrafanaRequestMaintenanceDow = "thursday"
)

// Automatic maintenance settings
type CreateDBAASServiceGrafanaRequestMaintenance struct {
	// Day of week for installing updates
	Dow CreateDBAASServiceGrafanaRequestMaintenanceDow `json:"dow" validate:"required"`
	// Time for installing updates, UTC
	Time string `json:"time" validate:"required,gte=8,lte=8"`
}

type CreateDBAASServiceGrafanaRequest struct {
	ForkFromService DBAASServiceName `json:"fork-from-service,omitempty" validate:"omitempty,gte=0,lte=63"`
	// Grafana settings
	GrafanaSettings *JSONSchemaGrafana `json:"grafana-settings,omitempty"`
	// Allowed CIDR address blocks for incoming connections
	IPFilter []string `json:"ip-filter,omitempty"`
	// Automatic maintenance settings
	Maintenance *CreateDBAASServiceGrafanaRequestMaintenance `json:"maintenance,omitempty"`
	// Subscription plan
	Plan string `json:"plan" validate:"required,gte=1,lte=128"`
	// Service is protected against termination and powering off
	TerminationProtection *bool `json:"termination-protection,omitempty"`
}

// Create a DBaaS Grafana service
func (c Client) CreateDBAASServiceGrafana(ctx context.Context, name string, req CreateDBAASServiceGrafanaRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-grafana/%v", name)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceGrafana: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceGrafana: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceGrafana: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceGrafana: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-dbaas-service-grafana")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceGrafana: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceGrafana: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceGrafana: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type UpdateDBAASServiceGrafanaRequestMaintenanceDow string

const (
	UpdateDBAASServiceGrafanaRequestMaintenanceDowSaturday  UpdateDBAASServiceGrafanaRequestMaintenanceDow = "saturday"
	UpdateDBAASServiceGrafanaRequestMaintenanceDowTuesday   UpdateDBAASServiceGrafanaRequestMaintenanceDow = "tuesday"
	UpdateDBAASServiceGrafanaRequestMaintenanceDowNever     UpdateDBAASServiceGrafanaRequestMaintenanceDow = "never"
	UpdateDBAASServiceGrafanaRequestMaintenanceDowWednesday UpdateDBAASServiceGrafanaRequestMaintenanceDow = "wednesday"
	UpdateDBAASServiceGrafanaRequestMaintenanceDowSunday    UpdateDBAASServiceGrafanaRequestMaintenanceDow = "sunday"
	UpdateDBAASServiceGrafanaRequestMaintenanceDowFriday    UpdateDBAASServiceGrafanaRequestMaintenanceDow = "friday"
	UpdateDBAASServiceGrafanaRequestMaintenanceDowMonday    UpdateDBAASServiceGrafanaRequestMaintenanceDow = "monday"
	UpdateDBAASServiceGrafanaRequestMaintenanceDowThursday  UpdateDBAASServiceGrafanaRequestMaintenanceDow = "thursday"
)

// Automatic maintenance settings
type UpdateDBAASServiceGrafanaRequestMaintenance struct {
	// Day of week for installing updates
	Dow UpdateDBAASServiceGrafanaRequestMaintenanceDow `json:"dow" validate:"required"`
	// Time for installing updates, UTC
	Time string `json:"time" validate:"required,gte=8,lte=8"`
}

type UpdateDBAASServiceGrafanaRequest struct {
	// Grafana settings
	GrafanaSettings *JSONSchemaGrafana `json:"grafana-settings,omitempty"`
	// Allowed CIDR address blocks for incoming connections
	IPFilter []string `json:"ip-filter,omitempty"`
	// Automatic maintenance settings
	Maintenance *UpdateDBAASServiceGrafanaRequestMaintenance `json:"maintenance,omitempty"`
	// Subscription plan
	Plan string `json:"plan,omitempty" validate:"omitempty,gte=1,lte=128"`
	// Service is protected against termination and powering off
	TerminationProtection *bool `json:"termination-protection,omitempty"`
}

func (c Client) UpdateDBAASServiceGrafana(ctx context.Context, name string, req UpdateDBAASServiceGrafanaRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-grafana/%v", name)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceGrafana: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceGrafana: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceGrafana: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceGrafana: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-dbaas-service-grafana")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceGrafana: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceGrafana: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceGrafana: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) StartDBAASGrafanaMaintenance(ctx context.Context, name string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-grafana/%v/maintenance/start", name)

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("StartDBAASGrafanaMaintenance: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("StartDBAASGrafanaMaintenance: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("StartDBAASGrafanaMaintenance: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "start-dbaas-grafana-maintenance")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("StartDBAASGrafanaMaintenance: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("StartDBAASGrafanaMaintenance: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("StartDBAASGrafanaMaintenance: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ResetDBAASGrafanaUserPasswordRequest struct {
	Password DBAASUserPassword `json:"password,omitempty" validate:"omitempty,gte=8,lte=256"`
}

// If no password is provided one will be generated automatically.
func (c Client) ResetDBAASGrafanaUserPassword(ctx context.Context, serviceName string, username string, req ResetDBAASGrafanaUserPasswordRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-grafana/%v/user/%v/password/reset", serviceName, username)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("ResetDBAASGrafanaUserPassword: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("ResetDBAASGrafanaUserPassword: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ResetDBAASGrafanaUserPassword: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ResetDBAASGrafanaUserPassword: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reset-dbaas-grafana-user-password")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ResetDBAASGrafanaUserPassword: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ResetDBAASGrafanaUserPassword: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ResetDBAASGrafanaUserPassword: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) RevealDBAASGrafanaUserPassword(ctx context.Context, serviceName string, username string) (*DBAASUserGrafanaSecrets, error) {
	path := fmt.Sprintf("/dbaas-grafana/%v/user/%v/password/reveal", serviceName, username)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("RevealDBAASGrafanaUserPassword: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("RevealDBAASGrafanaUserPassword: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("RevealDBAASGrafanaUserPassword: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reveal-dbaas-grafana-user-password")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("RevealDBAASGrafanaUserPassword: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("RevealDBAASGrafanaUserPassword: http response: %w", err)
	}

	bodyresp := new(DBAASUserGrafanaSecrets)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("RevealDBAASGrafanaUserPassword: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type CreateDBAASIntegrationRequest struct {
	DestService     DBAASServiceName     `json:"dest-service" validate:"required,gte=0,lte=63"`
	IntegrationType EnumIntegrationTypes `json:"integration-type" validate:"required"`
	// Integration settings
	Settings      map[string]any   `json:"settings,omitempty"`
	SourceService DBAASServiceName `json:"source-service" validate:"required,gte=0,lte=63"`
}

// [BETA] Create a new DBaaS integration between two services
func (c Client) CreateDBAASIntegration(ctx context.Context, req CreateDBAASIntegrationRequest) (*Operation, error) {
	path := "/dbaas-integration"

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASIntegration: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASIntegration: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateDBAASIntegration: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateDBAASIntegration: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-dbaas-integration")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASIntegration: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateDBAASIntegration: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateDBAASIntegration: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// The JSON schema representing the settings for the given integration type, source, and destination service types.
type ListDBAASIntegrationSettingsResponseSettings struct {
	AdditionalProperties *bool          `json:"additionalProperties,omitempty"`
	Properties           map[string]any `json:"properties,omitempty"`
	Title                string         `json:"title,omitempty"`
	Type                 string         `json:"type,omitempty"`
}

type ListDBAASIntegrationSettingsResponse struct {
	// The JSON schema representing the settings for the given integration type, source, and destination service types.
	Settings *ListDBAASIntegrationSettingsResponseSettings `json:"settings,omitempty"`
}

// [BETA] Get DBaaS integration settings
func (c Client) ListDBAASIntegrationSettings(ctx context.Context, integrationType string, sourceType string, destType string) (*ListDBAASIntegrationSettingsResponse, error) {
	path := fmt.Sprintf("/dbaas-integration-settings/%v/%v/%v", integrationType, sourceType, destType)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListDBAASIntegrationSettings: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListDBAASIntegrationSettings: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListDBAASIntegrationSettings: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-dbaas-integration-settings")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListDBAASIntegrationSettings: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListDBAASIntegrationSettings: http response: %w", err)
	}

	bodyresp := new(ListDBAASIntegrationSettingsResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListDBAASIntegrationSettings: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ListDBAASIntegrationTypesResponse struct {
	DBAASIntegrationTypes []DBAASIntegrationType `json:"dbaas-integration-types,omitempty"`
}

// [BETA] Get DBaaS integration types
func (c Client) ListDBAASIntegrationTypes(ctx context.Context) (*ListDBAASIntegrationTypesResponse, error) {
	path := "/dbaas-integration-types"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListDBAASIntegrationTypes: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListDBAASIntegrationTypes: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListDBAASIntegrationTypes: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-dbaas-integration-types")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListDBAASIntegrationTypes: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListDBAASIntegrationTypes: http response: %w", err)
	}

	bodyresp := new(ListDBAASIntegrationTypesResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListDBAASIntegrationTypes: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// [BETA] Delete a DBaaS Integration
func (c Client) DeleteDBAASIntegration(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-integration/%v", id)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASIntegration: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASIntegration: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASIntegration: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-dbaas-integration")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASIntegration: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteDBAASIntegration: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteDBAASIntegration: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// [BETA] Get a DBaaS Integration
func (c Client) GetDBAASIntegration(ctx context.Context, id UUID) (*DBAASIntegration, error) {
	path := fmt.Sprintf("/dbaas-integration/%v", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASIntegration: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASIntegration: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASIntegration: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-integration")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASIntegration: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASIntegration: http response: %w", err)
	}

	bodyresp := new(DBAASIntegration)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASIntegration: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type UpdateDBAASIntegrationRequest struct {
	// Integration settings
	Settings map[string]any `json:"settings" validate:"required"`
}

// [BETA] Update a existing DBaaS integration
func (c Client) UpdateDBAASIntegration(ctx context.Context, id UUID, req UpdateDBAASIntegrationRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-integration/%v", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASIntegration: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASIntegration: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASIntegration: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASIntegration: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-dbaas-integration")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASIntegration: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateDBAASIntegration: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateDBAASIntegration: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) DeleteDBAASServiceKafka(ctx context.Context, name string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-kafka/%v", name)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceKafka: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceKafka: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceKafka: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-dbaas-service-kafka")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceKafka: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceKafka: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceKafka: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) GetDBAASServiceKafka(ctx context.Context, name string) (*DBAASServiceKafka, error) {
	path := fmt.Sprintf("/dbaas-kafka/%v", name)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASServiceKafka: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceKafka: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceKafka: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-service-kafka")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASServiceKafka: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceKafka: http response: %w", err)
	}

	bodyresp := new(DBAASServiceKafka)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceKafka: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Kafka authentication methods
type CreateDBAASServiceKafkaRequestAuthenticationMethods struct {
	// Enable certificate/SSL authentication
	Certificate *bool `json:"certificate,omitempty"`
	// Enable SASL authentication
	Sasl *bool `json:"sasl,omitempty"`
}

type CreateDBAASServiceKafkaRequestMaintenanceDow string

const (
	CreateDBAASServiceKafkaRequestMaintenanceDowSaturday  CreateDBAASServiceKafkaRequestMaintenanceDow = "saturday"
	CreateDBAASServiceKafkaRequestMaintenanceDowTuesday   CreateDBAASServiceKafkaRequestMaintenanceDow = "tuesday"
	CreateDBAASServiceKafkaRequestMaintenanceDowNever     CreateDBAASServiceKafkaRequestMaintenanceDow = "never"
	CreateDBAASServiceKafkaRequestMaintenanceDowWednesday CreateDBAASServiceKafkaRequestMaintenanceDow = "wednesday"
	CreateDBAASServiceKafkaRequestMaintenanceDowSunday    CreateDBAASServiceKafkaRequestMaintenanceDow = "sunday"
	CreateDBAASServiceKafkaRequestMaintenanceDowFriday    CreateDBAASServiceKafkaRequestMaintenanceDow = "friday"
	CreateDBAASServiceKafkaRequestMaintenanceDowMonday    CreateDBAASServiceKafkaRequestMaintenanceDow = "monday"
	CreateDBAASServiceKafkaRequestMaintenanceDowThursday  CreateDBAASServiceKafkaRequestMaintenanceDow = "thursday"
)

// Automatic maintenance settings
type CreateDBAASServiceKafkaRequestMaintenance struct {
	// Day of week for installing updates
	Dow CreateDBAASServiceKafkaRequestMaintenanceDow `json:"dow" validate:"required"`
	// Time for installing updates, UTC
	Time string `json:"time" validate:"required,gte=8,lte=8"`
}

type CreateDBAASServiceKafkaRequest struct {
	// Kafka authentication methods
	AuthenticationMethods *CreateDBAASServiceKafkaRequestAuthenticationMethods `json:"authentication-methods,omitempty"`
	// Allow incoming connections from CIDR address block, e.g. '10.20.0.0/16'
	IPFilter []string `json:"ip-filter,omitempty"`
	// Allow clients to connect to kafka_connect from the public internet for service nodes that are in a project VPC or another type of private network
	KafkaConnectEnabled *bool `json:"kafka-connect-enabled,omitempty"`
	// Kafka Connect configuration values
	KafkaConnectSettings *JSONSchemaKafkaConnect `json:"kafka-connect-settings,omitempty"`
	// Enable Kafka-REST service
	KafkaRestEnabled *bool `json:"kafka-rest-enabled,omitempty"`
	// Kafka REST configuration
	KafkaRestSettings *JSONSchemaKafkaRest `json:"kafka-rest-settings,omitempty"`
	// Kafka broker configuration values
	KafkaSettings *JSONSchemaKafka `json:"kafka-settings,omitempty"`
	// Automatic maintenance settings
	Maintenance *CreateDBAASServiceKafkaRequestMaintenance `json:"maintenance,omitempty"`
	// Subscription plan
	Plan string `json:"plan" validate:"required,gte=1,lte=128"`
	// Enable Schema-Registry service
	SchemaRegistryEnabled *bool `json:"schema-registry-enabled,omitempty"`
	// Schema Registry configuration
	SchemaRegistrySettings *JSONSchemaSchemaRegistry `json:"schema-registry-settings,omitempty"`
	// Service is protected against termination and powering off
	TerminationProtection *bool `json:"termination-protection,omitempty"`
	// Kafka major version
	Version string `json:"version,omitempty" validate:"omitempty,gte=1"`
}

// Create a DBaaS Kafka service
func (c Client) CreateDBAASServiceKafka(ctx context.Context, name string, req CreateDBAASServiceKafkaRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-kafka/%v", name)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceKafka: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceKafka: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceKafka: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceKafka: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-dbaas-service-kafka")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceKafka: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceKafka: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceKafka: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Kafka authentication methods
type UpdateDBAASServiceKafkaRequestAuthenticationMethods struct {
	// Enable certificate/SSL authentication
	Certificate *bool `json:"certificate,omitempty"`
	// Enable SASL authentication
	Sasl *bool `json:"sasl,omitempty"`
}

type UpdateDBAASServiceKafkaRequestMaintenanceDow string

const (
	UpdateDBAASServiceKafkaRequestMaintenanceDowSaturday  UpdateDBAASServiceKafkaRequestMaintenanceDow = "saturday"
	UpdateDBAASServiceKafkaRequestMaintenanceDowTuesday   UpdateDBAASServiceKafkaRequestMaintenanceDow = "tuesday"
	UpdateDBAASServiceKafkaRequestMaintenanceDowNever     UpdateDBAASServiceKafkaRequestMaintenanceDow = "never"
	UpdateDBAASServiceKafkaRequestMaintenanceDowWednesday UpdateDBAASServiceKafkaRequestMaintenanceDow = "wednesday"
	UpdateDBAASServiceKafkaRequestMaintenanceDowSunday    UpdateDBAASServiceKafkaRequestMaintenanceDow = "sunday"
	UpdateDBAASServiceKafkaRequestMaintenanceDowFriday    UpdateDBAASServiceKafkaRequestMaintenanceDow = "friday"
	UpdateDBAASServiceKafkaRequestMaintenanceDowMonday    UpdateDBAASServiceKafkaRequestMaintenanceDow = "monday"
	UpdateDBAASServiceKafkaRequestMaintenanceDowThursday  UpdateDBAASServiceKafkaRequestMaintenanceDow = "thursday"
)

// Automatic maintenance settings
type UpdateDBAASServiceKafkaRequestMaintenance struct {
	// Day of week for installing updates
	Dow UpdateDBAASServiceKafkaRequestMaintenanceDow `json:"dow" validate:"required"`
	// Time for installing updates, UTC
	Time string `json:"time" validate:"required,gte=8,lte=8"`
}

type UpdateDBAASServiceKafkaRequest struct {
	// Kafka authentication methods
	AuthenticationMethods *UpdateDBAASServiceKafkaRequestAuthenticationMethods `json:"authentication-methods,omitempty"`
	// Allow incoming connections from CIDR address block, e.g. '10.20.0.0/16'
	IPFilter []string `json:"ip-filter,omitempty"`
	// Allow clients to connect to kafka_connect from the public internet for service nodes that are in a project VPC or another type of private network
	KafkaConnectEnabled *bool `json:"kafka-connect-enabled,omitempty"`
	// Kafka Connect configuration values
	KafkaConnectSettings *JSONSchemaKafkaConnect `json:"kafka-connect-settings,omitempty"`
	// Enable Kafka-REST service
	KafkaRestEnabled *bool `json:"kafka-rest-enabled,omitempty"`
	// Kafka REST configuration
	KafkaRestSettings *JSONSchemaKafkaRest `json:"kafka-rest-settings,omitempty"`
	// Kafka broker configuration values
	KafkaSettings *JSONSchemaKafka `json:"kafka-settings,omitempty"`
	// Automatic maintenance settings
	Maintenance *UpdateDBAASServiceKafkaRequestMaintenance `json:"maintenance,omitempty"`
	// Subscription plan
	Plan string `json:"plan,omitempty" validate:"omitempty,gte=1,lte=128"`
	// Enable Schema-Registry service
	SchemaRegistryEnabled *bool `json:"schema-registry-enabled,omitempty"`
	// Schema Registry configuration
	SchemaRegistrySettings *JSONSchemaSchemaRegistry `json:"schema-registry-settings,omitempty"`
	// Service is protected against termination and powering off
	TerminationProtection *bool `json:"termination-protection,omitempty"`
	// Kafka major version
	Version string `json:"version,omitempty" validate:"omitempty,gte=1"`
}

// Update a DBaaS Kafka service
func (c Client) UpdateDBAASServiceKafka(ctx context.Context, name string, req UpdateDBAASServiceKafkaRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-kafka/%v", name)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceKafka: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceKafka: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceKafka: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceKafka: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-dbaas-service-kafka")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceKafka: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceKafka: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceKafka: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) GetDBAASKafkaAclConfig(ctx context.Context, name string) (*DBAASKafkaAcls, error) {
	path := fmt.Sprintf("/dbaas-kafka/%v/acl-config", name)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASKafkaAclConfig: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASKafkaAclConfig: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASKafkaAclConfig: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-kafka-acl-config")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASKafkaAclConfig: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASKafkaAclConfig: http response: %w", err)
	}

	bodyresp := new(DBAASKafkaAcls)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASKafkaAclConfig: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) StartDBAASKafkaMaintenance(ctx context.Context, name string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-kafka/%v/maintenance/start", name)

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("StartDBAASKafkaMaintenance: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("StartDBAASKafkaMaintenance: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("StartDBAASKafkaMaintenance: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "start-dbaas-kafka-maintenance")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("StartDBAASKafkaMaintenance: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("StartDBAASKafkaMaintenance: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("StartDBAASKafkaMaintenance: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) CreateDBAASKafkaSchemaRegistryAclConfig(ctx context.Context, name string, req DBAASKafkaSchemaRegistryAclEntry) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-kafka/%v/schema-registry/acl-config", name)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASKafkaSchemaRegistryAclConfig: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASKafkaSchemaRegistryAclConfig: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateDBAASKafkaSchemaRegistryAclConfig: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateDBAASKafkaSchemaRegistryAclConfig: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-dbaas-kafka-schema-registry-acl-config")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASKafkaSchemaRegistryAclConfig: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateDBAASKafkaSchemaRegistryAclConfig: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateDBAASKafkaSchemaRegistryAclConfig: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) DeleteDBAASKafkaSchemaRegistryAclConfig(ctx context.Context, name string, aclID string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-kafka/%v/schema-registry/acl-config/%v", name, aclID)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASKafkaSchemaRegistryAclConfig: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASKafkaSchemaRegistryAclConfig: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASKafkaSchemaRegistryAclConfig: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-dbaas-kafka-schema-registry-acl-config")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASKafkaSchemaRegistryAclConfig: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteDBAASKafkaSchemaRegistryAclConfig: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteDBAASKafkaSchemaRegistryAclConfig: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) CreateDBAASKafkaTopicAclConfig(ctx context.Context, name string, req DBAASKafkaTopicAclEntry) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-kafka/%v/topic/acl-config", name)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASKafkaTopicAclConfig: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASKafkaTopicAclConfig: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateDBAASKafkaTopicAclConfig: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateDBAASKafkaTopicAclConfig: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-dbaas-kafka-topic-acl-config")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASKafkaTopicAclConfig: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateDBAASKafkaTopicAclConfig: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateDBAASKafkaTopicAclConfig: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) DeleteDBAASKafkaTopicAclConfig(ctx context.Context, name string, aclID string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-kafka/%v/topic/acl-config/%v", name, aclID)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASKafkaTopicAclConfig: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASKafkaTopicAclConfig: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASKafkaTopicAclConfig: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-dbaas-kafka-topic-acl-config")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASKafkaTopicAclConfig: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteDBAASKafkaTopicAclConfig: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteDBAASKafkaTopicAclConfig: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) RevealDBAASKafkaConnectPassword(ctx context.Context, serviceName string) (*DBAASUserKafkaConnectSecrets, error) {
	path := fmt.Sprintf("/dbaas-kafka/%v/connect/password/reveal", serviceName)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("RevealDBAASKafkaConnectPassword: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("RevealDBAASKafkaConnectPassword: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("RevealDBAASKafkaConnectPassword: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reveal-dbaas-kafka-connect-password")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("RevealDBAASKafkaConnectPassword: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("RevealDBAASKafkaConnectPassword: http response: %w", err)
	}

	bodyresp := new(DBAASUserKafkaConnectSecrets)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("RevealDBAASKafkaConnectPassword: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type CreateDBAASKafkaUserRequest struct {
	Username DBAASUserUsername `json:"username" validate:"required,gte=1,lte=64"`
}

func (c Client) CreateDBAASKafkaUser(ctx context.Context, serviceName string, req CreateDBAASKafkaUserRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-kafka/%v/user", serviceName)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASKafkaUser: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASKafkaUser: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateDBAASKafkaUser: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateDBAASKafkaUser: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-dbaas-kafka-user")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASKafkaUser: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateDBAASKafkaUser: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateDBAASKafkaUser: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) DeleteDBAASKafkaUser(ctx context.Context, serviceName string, username string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-kafka/%v/user/%v", serviceName, username)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASKafkaUser: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASKafkaUser: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASKafkaUser: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-dbaas-kafka-user")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASKafkaUser: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteDBAASKafkaUser: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteDBAASKafkaUser: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ResetDBAASKafkaUserPasswordRequest struct {
	Password DBAASUserPassword `json:"password,omitempty" validate:"omitempty,gte=8,lte=256"`
}

// If no password is provided one will be generated automatically.
func (c Client) ResetDBAASKafkaUserPassword(ctx context.Context, serviceName string, username string, req ResetDBAASKafkaUserPasswordRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-kafka/%v/user/%v/password/reset", serviceName, username)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("ResetDBAASKafkaUserPassword: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("ResetDBAASKafkaUserPassword: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ResetDBAASKafkaUserPassword: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ResetDBAASKafkaUserPassword: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reset-dbaas-kafka-user-password")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ResetDBAASKafkaUserPassword: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ResetDBAASKafkaUserPassword: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ResetDBAASKafkaUserPassword: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) RevealDBAASKafkaUserPassword(ctx context.Context, serviceName string, username string) (*DBAASUserKafkaSecrets, error) {
	path := fmt.Sprintf("/dbaas-kafka/%v/user/%v/password/reveal", serviceName, username)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("RevealDBAASKafkaUserPassword: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("RevealDBAASKafkaUserPassword: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("RevealDBAASKafkaUserPassword: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reveal-dbaas-kafka-user-password")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("RevealDBAASKafkaUserPassword: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("RevealDBAASKafkaUserPassword: http response: %w", err)
	}

	bodyresp := new(DBAASUserKafkaSecrets)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("RevealDBAASKafkaUserPassword: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Get a DBaaS migration status
func (c Client) GetDBAASMigrationStatus(ctx context.Context, name string) (*DBAASMigrationStatus, error) {
	path := fmt.Sprintf("/dbaas-migration-status/%v", name)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASMigrationStatus: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASMigrationStatus: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASMigrationStatus: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-migration-status")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASMigrationStatus: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASMigrationStatus: http response: %w", err)
	}

	bodyresp := new(DBAASMigrationStatus)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASMigrationStatus: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) DeleteDBAASServiceMysql(ctx context.Context, name string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-mysql/%v", name)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceMysql: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceMysql: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceMysql: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-dbaas-service-mysql")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceMysql: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceMysql: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceMysql: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Get a DBaaS MySQL service
func (c Client) GetDBAASServiceMysql(ctx context.Context, name string) (*DBAASServiceMysql, error) {
	path := fmt.Sprintf("/dbaas-mysql/%v", name)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASServiceMysql: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceMysql: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceMysql: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-service-mysql")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASServiceMysql: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceMysql: http response: %w", err)
	}

	bodyresp := new(DBAASServiceMysql)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceMysql: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type CreateDBAASServiceMysqlRequestBackupSchedule struct {
	// The hour of day (in UTC) when backup for the service is started. New backup is only started if previous backup has already completed.
	BackupHour *int64 `json:"backup-hour,omitempty" validate:"omitempty,gte=0,lte=23"`
	// The minute of an hour when backup for the service is started. New backup is only started if previous backup has already completed.
	BackupMinute *int64 `json:"backup-minute,omitempty" validate:"omitempty,gte=0,lte=59"`
}

type CreateDBAASServiceMysqlRequestIntegrationsType string

const (
	CreateDBAASServiceMysqlRequestIntegrationsTypeReadReplica CreateDBAASServiceMysqlRequestIntegrationsType = "read_replica"
)

type CreateDBAASServiceMysqlRequestIntegrations struct {
	DestService DBAASServiceName `json:"dest-service,omitempty" validate:"omitempty,gte=0,lte=63"`
	// Integration settings
	Settings      map[string]any   `json:"settings,omitempty"`
	SourceService DBAASServiceName `json:"source-service,omitempty" validate:"omitempty,gte=0,lte=63"`
	// Integration type
	Type CreateDBAASServiceMysqlRequestIntegrationsType `json:"type" validate:"required"`
}

type CreateDBAASServiceMysqlRequestMaintenanceDow string

const (
	CreateDBAASServiceMysqlRequestMaintenanceDowSaturday  CreateDBAASServiceMysqlRequestMaintenanceDow = "saturday"
	CreateDBAASServiceMysqlRequestMaintenanceDowTuesday   CreateDBAASServiceMysqlRequestMaintenanceDow = "tuesday"
	CreateDBAASServiceMysqlRequestMaintenanceDowNever     CreateDBAASServiceMysqlRequestMaintenanceDow = "never"
	CreateDBAASServiceMysqlRequestMaintenanceDowWednesday CreateDBAASServiceMysqlRequestMaintenanceDow = "wednesday"
	CreateDBAASServiceMysqlRequestMaintenanceDowSunday    CreateDBAASServiceMysqlRequestMaintenanceDow = "sunday"
	CreateDBAASServiceMysqlRequestMaintenanceDowFriday    CreateDBAASServiceMysqlRequestMaintenanceDow = "friday"
	CreateDBAASServiceMysqlRequestMaintenanceDowMonday    CreateDBAASServiceMysqlRequestMaintenanceDow = "monday"
	CreateDBAASServiceMysqlRequestMaintenanceDowThursday  CreateDBAASServiceMysqlRequestMaintenanceDow = "thursday"
)

// Automatic maintenance settings
type CreateDBAASServiceMysqlRequestMaintenance struct {
	// Day of week for installing updates
	Dow CreateDBAASServiceMysqlRequestMaintenanceDow `json:"dow" validate:"required"`
	// Time for installing updates, UTC
	Time string `json:"time" validate:"required,gte=8,lte=8"`
}

// Migrate data from existing server
type CreateDBAASServiceMysqlRequestMigration struct {
	// Database name for bootstrapping the initial connection
	Dbname string `json:"dbname,omitempty" validate:"omitempty,gte=1,lte=63"`
	// Hostname or IP address of the server where to migrate data from
	Host string `json:"host" validate:"required,gte=1,lte=255"`
	// Comma-separated list of databases, which should be ignored during migration (supported by MySQL only at the moment)
	IgnoreDbs string              `json:"ignore-dbs,omitempty" validate:"omitempty,gte=1,lte=2048"`
	Method    EnumMigrationMethod `json:"method,omitempty"`
	// Password for authentication with the server where to migrate data from
	Password string `json:"password,omitempty" validate:"omitempty,gte=1,lte=255"`
	// Port number of the server where to migrate data from
	Port int64 `json:"port" validate:"required,gte=1,lte=65535"`
	// The server where to migrate data from is secured with SSL
	SSL *bool `json:"ssl,omitempty"`
	// User name for authentication with the server where to migrate data from
	Username string `json:"username,omitempty" validate:"omitempty,gte=1,lte=255"`
}

type CreateDBAASServiceMysqlRequest struct {
	AdminPassword string `json:"admin-password,omitempty" validate:"omitempty,gte=8,lte=256"`
	// Custom username for admin user. This must be set only when a new service is being created.
	AdminUsername  string                                        `json:"admin-username,omitempty" validate:"omitempty,gte=1,lte=64"`
	BackupSchedule *CreateDBAASServiceMysqlRequestBackupSchedule `json:"backup-schedule,omitempty"`
	// The minimum amount of time in seconds to keep binlog entries before deletion. This may be extended for services that require binlog entries for longer than the default for example if using the MySQL Debezium Kafka connector.
	BinlogRetentionPeriod int64            `json:"binlog-retention-period,omitempty" validate:"omitempty,gte=600,lte=86400"`
	ForkFromService       DBAASServiceName `json:"fork-from-service,omitempty" validate:"omitempty,gte=0,lte=63"`
	// Service integrations to be enabled when creating the service.
	Integrations []CreateDBAASServiceMysqlRequestIntegrations `json:"integrations,omitempty"`
	// Allow incoming connections from CIDR address block, e.g. '10.20.0.0/16'
	IPFilter []string `json:"ip-filter,omitempty"`
	// Automatic maintenance settings
	Maintenance *CreateDBAASServiceMysqlRequestMaintenance `json:"maintenance,omitempty"`
	// Migrate data from existing server
	Migration *CreateDBAASServiceMysqlRequestMigration `json:"migration,omitempty"`
	// mysql.conf configuration values
	MysqlSettings *JSONSchemaMysql `json:"mysql-settings,omitempty"`
	// Subscription plan
	Plan string `json:"plan" validate:"required,gte=1,lte=128"`
	// ISO time of a backup to recover from for services that support arbitrary times
	RecoveryBackupTime string `json:"recovery-backup-time,omitempty" validate:"omitempty,gte=1"`
	// Service is protected against termination and powering off
	TerminationProtection *bool `json:"termination-protection,omitempty"`
	// MySQL major version
	Version string `json:"version,omitempty" validate:"omitempty,gte=1"`
}

// Create a DBaaS MySQL service
func (c Client) CreateDBAASServiceMysql(ctx context.Context, name string, req CreateDBAASServiceMysqlRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-mysql/%v", name)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceMysql: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceMysql: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceMysql: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceMysql: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-dbaas-service-mysql")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceMysql: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceMysql: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceMysql: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type UpdateDBAASServiceMysqlRequestBackupSchedule struct {
	// The hour of day (in UTC) when backup for the service is started. New backup is only started if previous backup has already completed.
	BackupHour *int64 `json:"backup-hour,omitempty" validate:"omitempty,gte=0,lte=23"`
	// The minute of an hour when backup for the service is started. New backup is only started if previous backup has already completed.
	BackupMinute *int64 `json:"backup-minute,omitempty" validate:"omitempty,gte=0,lte=59"`
}

type UpdateDBAASServiceMysqlRequestMaintenanceDow string

const (
	UpdateDBAASServiceMysqlRequestMaintenanceDowSaturday  UpdateDBAASServiceMysqlRequestMaintenanceDow = "saturday"
	UpdateDBAASServiceMysqlRequestMaintenanceDowTuesday   UpdateDBAASServiceMysqlRequestMaintenanceDow = "tuesday"
	UpdateDBAASServiceMysqlRequestMaintenanceDowNever     UpdateDBAASServiceMysqlRequestMaintenanceDow = "never"
	UpdateDBAASServiceMysqlRequestMaintenanceDowWednesday UpdateDBAASServiceMysqlRequestMaintenanceDow = "wednesday"
	UpdateDBAASServiceMysqlRequestMaintenanceDowSunday    UpdateDBAASServiceMysqlRequestMaintenanceDow = "sunday"
	UpdateDBAASServiceMysqlRequestMaintenanceDowFriday    UpdateDBAASServiceMysqlRequestMaintenanceDow = "friday"
	UpdateDBAASServiceMysqlRequestMaintenanceDowMonday    UpdateDBAASServiceMysqlRequestMaintenanceDow = "monday"
	UpdateDBAASServiceMysqlRequestMaintenanceDowThursday  UpdateDBAASServiceMysqlRequestMaintenanceDow = "thursday"
)

// Automatic maintenance settings
type UpdateDBAASServiceMysqlRequestMaintenance struct {
	// Day of week for installing updates
	Dow UpdateDBAASServiceMysqlRequestMaintenanceDow `json:"dow" validate:"required"`
	// Time for installing updates, UTC
	Time string `json:"time" validate:"required,gte=8,lte=8"`
}

// Migrate data from existing server
type UpdateDBAASServiceMysqlRequestMigration struct {
	// Database name for bootstrapping the initial connection
	Dbname string `json:"dbname,omitempty" validate:"omitempty,gte=1,lte=63"`
	// Hostname or IP address of the server where to migrate data from
	Host string `json:"host" validate:"required,gte=1,lte=255"`
	// Comma-separated list of databases, which should be ignored during migration (supported by MySQL only at the moment)
	IgnoreDbs string              `json:"ignore-dbs,omitempty" validate:"omitempty,gte=1,lte=2048"`
	Method    EnumMigrationMethod `json:"method,omitempty"`
	// Password for authentication with the server where to migrate data from
	Password string `json:"password,omitempty" validate:"omitempty,gte=1,lte=255"`
	// Port number of the server where to migrate data from
	Port int64 `json:"port" validate:"required,gte=1,lte=65535"`
	// The server where to migrate data from is secured with SSL
	SSL *bool `json:"ssl,omitempty"`
	// User name for authentication with the server where to migrate data from
	Username string `json:"username,omitempty" validate:"omitempty,gte=1,lte=255"`
}

type UpdateDBAASServiceMysqlRequest struct {
	BackupSchedule *UpdateDBAASServiceMysqlRequestBackupSchedule `json:"backup-schedule,omitempty"`
	// The minimum amount of time in seconds to keep binlog entries before deletion. This may be extended for services that require binlog entries for longer than the default for example if using the MySQL Debezium Kafka connector.
	BinlogRetentionPeriod int64 `json:"binlog-retention-period,omitempty" validate:"omitempty,gte=600,lte=86400"`
	// Allow incoming connections from CIDR address block, e.g. '10.20.0.0/16'
	IPFilter []string `json:"ip-filter,omitempty"`
	// Automatic maintenance settings
	Maintenance *UpdateDBAASServiceMysqlRequestMaintenance `json:"maintenance,omitempty"`
	// Migrate data from existing server
	Migration *UpdateDBAASServiceMysqlRequestMigration `json:"migration,omitempty"`
	// mysql.conf configuration values
	MysqlSettings *JSONSchemaMysql `json:"mysql-settings,omitempty"`
	// Subscription plan
	Plan string `json:"plan,omitempty" validate:"omitempty,gte=1,lte=128"`
	// Service is protected against termination and powering off
	TerminationProtection *bool `json:"termination-protection,omitempty"`
	// MySQL version
	Version string `json:"version,omitempty"`
}

// Update a DBaaS MySQL service
func (c Client) UpdateDBAASServiceMysql(ctx context.Context, name string, req UpdateDBAASServiceMysqlRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-mysql/%v", name)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceMysql: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceMysql: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceMysql: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceMysql: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-dbaas-service-mysql")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceMysql: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceMysql: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceMysql: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) EnableDBAASMysqlWrites(ctx context.Context, name string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-mysql/%v/enable/writes", name)

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("EnableDBAASMysqlWrites: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("EnableDBAASMysqlWrites: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("EnableDBAASMysqlWrites: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "enable-dbaas-mysql-writes")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("EnableDBAASMysqlWrites: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("EnableDBAASMysqlWrites: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("EnableDBAASMysqlWrites: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) StartDBAASMysqlMaintenance(ctx context.Context, name string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-mysql/%v/maintenance/start", name)

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("StartDBAASMysqlMaintenance: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("StartDBAASMysqlMaintenance: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("StartDBAASMysqlMaintenance: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "start-dbaas-mysql-maintenance")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("StartDBAASMysqlMaintenance: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("StartDBAASMysqlMaintenance: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("StartDBAASMysqlMaintenance: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) StopDBAASMysqlMigration(ctx context.Context, name string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-mysql/%v/migration/stop", name)

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("StopDBAASMysqlMigration: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("StopDBAASMysqlMigration: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("StopDBAASMysqlMigration: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "stop-dbaas-mysql-migration")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("StopDBAASMysqlMigration: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("StopDBAASMysqlMigration: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("StopDBAASMysqlMigration: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type CreateDBAASMysqlDatabaseRequest struct {
	DatabaseName DBAASDatabaseName `json:"database-name" validate:"required,gte=1,lte=40"`
}

func (c Client) CreateDBAASMysqlDatabase(ctx context.Context, serviceName string, req CreateDBAASMysqlDatabaseRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-mysql/%v/database", serviceName)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASMysqlDatabase: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASMysqlDatabase: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateDBAASMysqlDatabase: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateDBAASMysqlDatabase: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-dbaas-mysql-database")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASMysqlDatabase: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateDBAASMysqlDatabase: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateDBAASMysqlDatabase: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) DeleteDBAASMysqlDatabase(ctx context.Context, serviceName string, databaseName string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-mysql/%v/database/%v", serviceName, databaseName)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASMysqlDatabase: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASMysqlDatabase: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASMysqlDatabase: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-dbaas-mysql-database")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASMysqlDatabase: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteDBAASMysqlDatabase: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteDBAASMysqlDatabase: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type CreateDBAASMysqlUserRequest struct {
	Authentication EnumMysqlAuthenticationPlugin `json:"authentication,omitempty"`
	Username       DBAASUserUsername             `json:"username" validate:"required,gte=1,lte=64"`
}

func (c Client) CreateDBAASMysqlUser(ctx context.Context, serviceName string, req CreateDBAASMysqlUserRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-mysql/%v/user", serviceName)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASMysqlUser: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASMysqlUser: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateDBAASMysqlUser: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateDBAASMysqlUser: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-dbaas-mysql-user")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASMysqlUser: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateDBAASMysqlUser: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateDBAASMysqlUser: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) DeleteDBAASMysqlUser(ctx context.Context, serviceName string, username string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-mysql/%v/user/%v", serviceName, username)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASMysqlUser: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASMysqlUser: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASMysqlUser: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-dbaas-mysql-user")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASMysqlUser: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteDBAASMysqlUser: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteDBAASMysqlUser: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ResetDBAASMysqlUserPasswordRequest struct {
	Authentication EnumMysqlAuthenticationPlugin `json:"authentication,omitempty"`
	Password       DBAASUserPassword             `json:"password,omitempty" validate:"omitempty,gte=8,lte=256"`
}

// If no password is provided one will be generated automatically.
func (c Client) ResetDBAASMysqlUserPassword(ctx context.Context, serviceName string, username string, req ResetDBAASMysqlUserPasswordRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-mysql/%v/user/%v/password/reset", serviceName, username)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("ResetDBAASMysqlUserPassword: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("ResetDBAASMysqlUserPassword: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ResetDBAASMysqlUserPassword: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ResetDBAASMysqlUserPassword: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reset-dbaas-mysql-user-password")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ResetDBAASMysqlUserPassword: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ResetDBAASMysqlUserPassword: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ResetDBAASMysqlUserPassword: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) RevealDBAASMysqlUserPassword(ctx context.Context, serviceName string, username string) (*DBAASUserMysqlSecrets, error) {
	path := fmt.Sprintf("/dbaas-mysql/%v/user/%v/password/reveal", serviceName, username)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("RevealDBAASMysqlUserPassword: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("RevealDBAASMysqlUserPassword: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("RevealDBAASMysqlUserPassword: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reveal-dbaas-mysql-user-password")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("RevealDBAASMysqlUserPassword: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("RevealDBAASMysqlUserPassword: http response: %w", err)
	}

	bodyresp := new(DBAASUserMysqlSecrets)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("RevealDBAASMysqlUserPassword: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) DeleteDBAASServiceOpensearch(ctx context.Context, name string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-opensearch/%v", name)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceOpensearch: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceOpensearch: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceOpensearch: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-dbaas-service-opensearch")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceOpensearch: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceOpensearch: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceOpensearch: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Get a DBaaS OpenSearch service
func (c Client) GetDBAASServiceOpensearch(ctx context.Context, name string) (*DBAASServiceOpensearch, error) {
	path := fmt.Sprintf("/dbaas-opensearch/%v", name)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASServiceOpensearch: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceOpensearch: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceOpensearch: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-service-opensearch")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASServiceOpensearch: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceOpensearch: http response: %w", err)
	}

	bodyresp := new(DBAASServiceOpensearch)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceOpensearch: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type CreateDBAASServiceOpensearchRequestIndexPatternsSortingAlgorithm string

const (
	CreateDBAASServiceOpensearchRequestIndexPatternsSortingAlgorithmAlphabetical CreateDBAASServiceOpensearchRequestIndexPatternsSortingAlgorithm = "alphabetical"
	CreateDBAASServiceOpensearchRequestIndexPatternsSortingAlgorithmCreationDate CreateDBAASServiceOpensearchRequestIndexPatternsSortingAlgorithm = "creation_date"
)

type CreateDBAASServiceOpensearchRequestIndexPatterns struct {
	// Maximum number of indexes to keep
	MaxIndexCount *int64 `json:"max-index-count,omitempty" validate:"omitempty,gte=0"`
	// fnmatch pattern
	Pattern string `json:"pattern,omitempty" validate:"omitempty,lte=1024"`
	// Deletion sorting algorithm
	SortingAlgorithm CreateDBAASServiceOpensearchRequestIndexPatternsSortingAlgorithm `json:"sorting-algorithm,omitempty"`
}

// Template settings for all new indexes
type CreateDBAASServiceOpensearchRequestIndexTemplate struct {
	// The maximum number of nested JSON objects that a single document can contain across all nested types. This limit helps to prevent out of memory errors when a document contains too many nested objects. Default is 10000.
	MappingNestedObjectsLimit *int64 `json:"mapping-nested-objects-limit,omitempty" validate:"omitempty,gte=0,lte=100000"`
	// The number of replicas each primary shard has.
	NumberOfReplicas *int64 `json:"number-of-replicas,omitempty" validate:"omitempty,gte=0,lte=29"`
	// The number of primary shards that an index should have.
	NumberOfShards int64 `json:"number-of-shards,omitempty" validate:"omitempty,gte=1,lte=1024"`
}

type CreateDBAASServiceOpensearchRequestMaintenanceDow string

const (
	CreateDBAASServiceOpensearchRequestMaintenanceDowSaturday  CreateDBAASServiceOpensearchRequestMaintenanceDow = "saturday"
	CreateDBAASServiceOpensearchRequestMaintenanceDowTuesday   CreateDBAASServiceOpensearchRequestMaintenanceDow = "tuesday"
	CreateDBAASServiceOpensearchRequestMaintenanceDowNever     CreateDBAASServiceOpensearchRequestMaintenanceDow = "never"
	CreateDBAASServiceOpensearchRequestMaintenanceDowWednesday CreateDBAASServiceOpensearchRequestMaintenanceDow = "wednesday"
	CreateDBAASServiceOpensearchRequestMaintenanceDowSunday    CreateDBAASServiceOpensearchRequestMaintenanceDow = "sunday"
	CreateDBAASServiceOpensearchRequestMaintenanceDowFriday    CreateDBAASServiceOpensearchRequestMaintenanceDow = "friday"
	CreateDBAASServiceOpensearchRequestMaintenanceDowMonday    CreateDBAASServiceOpensearchRequestMaintenanceDow = "monday"
	CreateDBAASServiceOpensearchRequestMaintenanceDowThursday  CreateDBAASServiceOpensearchRequestMaintenanceDow = "thursday"
)

// Automatic maintenance settings
type CreateDBAASServiceOpensearchRequestMaintenance struct {
	// Day of week for installing updates
	Dow CreateDBAASServiceOpensearchRequestMaintenanceDow `json:"dow" validate:"required"`
	// Time for installing updates, UTC
	Time string `json:"time" validate:"required,gte=8,lte=8"`
}

// OpenSearch Dashboards settings
type CreateDBAASServiceOpensearchRequestOpensearchDashboards struct {
	// Enable or disable OpenSearch Dashboards (default: true)
	Enabled *bool `json:"enabled,omitempty"`
	// Limits the maximum amount of memory (in MiB) the OpenSearch Dashboards process can use. This sets the max_old_space_size option of the nodejs running the OpenSearch Dashboards. Note: the memory reserved by OpenSearch Dashboards is not available for OpenSearch. (default: 128)
	MaxOldSpaceSize int64 `json:"max-old-space-size,omitempty" validate:"omitempty,gte=64,lte=1024"`
	// Timeout in milliseconds for requests made by OpenSearch Dashboards towards OpenSearch (default: 30000)
	OpensearchRequestTimeout int64 `json:"opensearch-request-timeout,omitempty" validate:"omitempty,gte=5000,lte=120000"`
}

type CreateDBAASServiceOpensearchRequest struct {
	ForkFromService DBAASServiceName `json:"fork-from-service,omitempty" validate:"omitempty,gte=0,lte=63"`
	// Allows you to create glob style patterns and set a max number of indexes matching this pattern you want to keep. Creating indexes exceeding this value will cause the oldest one to get deleted. You could for example create a pattern looking like 'logs.?' and then create index logs.1, logs.2 etc, it will delete logs.1 once you create logs.6. Do note 'logs.?' does not apply to logs.10. Note: Setting max_index_count to 0 will do nothing and the pattern gets ignored.
	IndexPatterns []CreateDBAASServiceOpensearchRequestIndexPatterns `json:"index-patterns,omitempty"`
	// Template settings for all new indexes
	IndexTemplate *CreateDBAASServiceOpensearchRequestIndexTemplate `json:"index-template,omitempty"`
	// Allow incoming connections from CIDR address block, e.g. '10.20.0.0/16'
	IPFilter []string `json:"ip-filter,omitempty"`
	// Aiven automation resets index.refresh_interval to default value for every index to be sure that indices are always visible to search. If it doesn't fit your case, you can disable this by setting up this flag to true.
	KeepIndexRefreshInterval *bool `json:"keep-index-refresh-interval,omitempty"`
	// Automatic maintenance settings
	Maintenance *CreateDBAASServiceOpensearchRequestMaintenance `json:"maintenance,omitempty"`
	// Maximum number of indexes to keep before deleting the oldest one
	MaxIndexCount *int64 `json:"max-index-count,omitempty" validate:"omitempty,gte=0"`
	// OpenSearch Dashboards settings
	OpensearchDashboards *CreateDBAASServiceOpensearchRequestOpensearchDashboards `json:"opensearch-dashboards,omitempty"`
	// OpenSearch settings
	OpensearchSettings *JSONSchemaOpensearch `json:"opensearch-settings,omitempty"`
	// Subscription plan
	Plan string `json:"plan" validate:"required,gte=1,lte=128"`
	// Name of a backup to recover from for services that support backup names
	RecoveryBackupName string `json:"recovery-backup-name,omitempty" validate:"omitempty,gte=1"`
	// Service is protected against termination and powering off
	TerminationProtection *bool `json:"termination-protection,omitempty"`
	// OpenSearch major version
	Version string `json:"version,omitempty" validate:"omitempty,gte=1"`
}

// Create a DBaaS OpenSearch service
func (c Client) CreateDBAASServiceOpensearch(ctx context.Context, name string, req CreateDBAASServiceOpensearchRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-opensearch/%v", name)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceOpensearch: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceOpensearch: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceOpensearch: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceOpensearch: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-dbaas-service-opensearch")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceOpensearch: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceOpensearch: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceOpensearch: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type UpdateDBAASServiceOpensearchRequestIndexPatternsSortingAlgorithm string

const (
	UpdateDBAASServiceOpensearchRequestIndexPatternsSortingAlgorithmAlphabetical UpdateDBAASServiceOpensearchRequestIndexPatternsSortingAlgorithm = "alphabetical"
	UpdateDBAASServiceOpensearchRequestIndexPatternsSortingAlgorithmCreationDate UpdateDBAASServiceOpensearchRequestIndexPatternsSortingAlgorithm = "creation_date"
)

type UpdateDBAASServiceOpensearchRequestIndexPatterns struct {
	// Maximum number of indexes to keep
	MaxIndexCount *int64 `json:"max-index-count,omitempty" validate:"omitempty,gte=0"`
	// fnmatch pattern
	Pattern string `json:"pattern,omitempty" validate:"omitempty,lte=1024"`
	// Deletion sorting algorithm
	SortingAlgorithm UpdateDBAASServiceOpensearchRequestIndexPatternsSortingAlgorithm `json:"sorting-algorithm,omitempty"`
}

// Template settings for all new indexes
type UpdateDBAASServiceOpensearchRequestIndexTemplate struct {
	// The maximum number of nested JSON objects that a single document can contain across all nested types. This limit helps to prevent out of memory errors when a document contains too many nested objects. Default is 10000.
	MappingNestedObjectsLimit *int64 `json:"mapping-nested-objects-limit,omitempty" validate:"omitempty,gte=0,lte=100000"`
	// The number of replicas each primary shard has.
	NumberOfReplicas *int64 `json:"number-of-replicas,omitempty" validate:"omitempty,gte=0,lte=29"`
	// The number of primary shards that an index should have.
	NumberOfShards int64 `json:"number-of-shards,omitempty" validate:"omitempty,gte=1,lte=1024"`
}

type UpdateDBAASServiceOpensearchRequestMaintenanceDow string

const (
	UpdateDBAASServiceOpensearchRequestMaintenanceDowSaturday  UpdateDBAASServiceOpensearchRequestMaintenanceDow = "saturday"
	UpdateDBAASServiceOpensearchRequestMaintenanceDowTuesday   UpdateDBAASServiceOpensearchRequestMaintenanceDow = "tuesday"
	UpdateDBAASServiceOpensearchRequestMaintenanceDowNever     UpdateDBAASServiceOpensearchRequestMaintenanceDow = "never"
	UpdateDBAASServiceOpensearchRequestMaintenanceDowWednesday UpdateDBAASServiceOpensearchRequestMaintenanceDow = "wednesday"
	UpdateDBAASServiceOpensearchRequestMaintenanceDowSunday    UpdateDBAASServiceOpensearchRequestMaintenanceDow = "sunday"
	UpdateDBAASServiceOpensearchRequestMaintenanceDowFriday    UpdateDBAASServiceOpensearchRequestMaintenanceDow = "friday"
	UpdateDBAASServiceOpensearchRequestMaintenanceDowMonday    UpdateDBAASServiceOpensearchRequestMaintenanceDow = "monday"
	UpdateDBAASServiceOpensearchRequestMaintenanceDowThursday  UpdateDBAASServiceOpensearchRequestMaintenanceDow = "thursday"
)

// Automatic maintenance settings
type UpdateDBAASServiceOpensearchRequestMaintenance struct {
	// Day of week for installing updates
	Dow UpdateDBAASServiceOpensearchRequestMaintenanceDow `json:"dow" validate:"required"`
	// Time for installing updates, UTC
	Time string `json:"time" validate:"required,gte=8,lte=8"`
}

// OpenSearch Dashboards settings
type UpdateDBAASServiceOpensearchRequestOpensearchDashboards struct {
	// Enable or disable OpenSearch Dashboards (default: true)
	Enabled *bool `json:"enabled,omitempty"`
	// Limits the maximum amount of memory (in MiB) the OpenSearch Dashboards process can use. This sets the max_old_space_size option of the nodejs running the OpenSearch Dashboards. Note: the memory reserved by OpenSearch Dashboards is not available for OpenSearch. (default: 128)
	MaxOldSpaceSize int64 `json:"max-old-space-size,omitempty" validate:"omitempty,gte=64,lte=1024"`
	// Timeout in milliseconds for requests made by OpenSearch Dashboards towards OpenSearch (default: 30000)
	OpensearchRequestTimeout int64 `json:"opensearch-request-timeout,omitempty" validate:"omitempty,gte=5000,lte=120000"`
}

type UpdateDBAASServiceOpensearchRequest struct {
	// Allows you to create glob style patterns and set a max number of indexes matching this pattern you want to keep. Creating indexes exceeding this value will cause the oldest one to get deleted. You could for example create a pattern looking like 'logs.?' and then create index logs.1, logs.2 etc, it will delete logs.1 once you create logs.6. Do note 'logs.?' does not apply to logs.10. Note: Setting max_index_count to 0 will do nothing and the pattern gets ignored.
	IndexPatterns []UpdateDBAASServiceOpensearchRequestIndexPatterns `json:"index-patterns,omitempty"`
	// Template settings for all new indexes
	IndexTemplate *UpdateDBAASServiceOpensearchRequestIndexTemplate `json:"index-template,omitempty"`
	// Allow incoming connections from CIDR address block, e.g. '10.20.0.0/16'
	IPFilter []string `json:"ip-filter,omitempty"`
	// Aiven automation resets index.refresh_interval to default value for every index to be sure that indices are always visible to search. If it doesn't fit your case, you can disable this by setting up this flag to true.
	KeepIndexRefreshInterval *bool `json:"keep-index-refresh-interval,omitempty"`
	// Automatic maintenance settings
	Maintenance *UpdateDBAASServiceOpensearchRequestMaintenance `json:"maintenance,omitempty"`
	// Maximum number of indexes to keep before deleting the oldest one
	MaxIndexCount *int64 `json:"max-index-count,omitempty" validate:"omitempty,gte=0"`
	// OpenSearch Dashboards settings
	OpensearchDashboards *UpdateDBAASServiceOpensearchRequestOpensearchDashboards `json:"opensearch-dashboards,omitempty"`
	// OpenSearch settings
	OpensearchSettings *JSONSchemaOpensearch `json:"opensearch-settings,omitempty"`
	// Subscription plan
	Plan string `json:"plan,omitempty" validate:"omitempty,gte=1,lte=128"`
	// Service is protected against termination and powering off
	TerminationProtection *bool `json:"termination-protection,omitempty"`
	// Version
	Version string `json:"version,omitempty"`
}

// Update a DBaaS OpenSearch service
func (c Client) UpdateDBAASServiceOpensearch(ctx context.Context, name string, req UpdateDBAASServiceOpensearchRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-opensearch/%v", name)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceOpensearch: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceOpensearch: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceOpensearch: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceOpensearch: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-dbaas-service-opensearch")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceOpensearch: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceOpensearch: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceOpensearch: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) GetDBAASOpensearchAclConfig(ctx context.Context, name string) (*DBAASOpensearchAclConfig, error) {
	path := fmt.Sprintf("/dbaas-opensearch/%v/acl-config", name)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASOpensearchAclConfig: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASOpensearchAclConfig: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASOpensearchAclConfig: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-opensearch-acl-config")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASOpensearchAclConfig: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASOpensearchAclConfig: http response: %w", err)
	}

	bodyresp := new(DBAASOpensearchAclConfig)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASOpensearchAclConfig: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) UpdateDBAASOpensearchAclConfig(ctx context.Context, name string, req DBAASOpensearchAclConfig) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-opensearch/%v/acl-config", name)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASOpensearchAclConfig: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASOpensearchAclConfig: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASOpensearchAclConfig: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASOpensearchAclConfig: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-dbaas-opensearch-acl-config")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASOpensearchAclConfig: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateDBAASOpensearchAclConfig: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateDBAASOpensearchAclConfig: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) StartDBAASOpensearchMaintenance(ctx context.Context, name string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-opensearch/%v/maintenance/start", name)

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("StartDBAASOpensearchMaintenance: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("StartDBAASOpensearchMaintenance: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("StartDBAASOpensearchMaintenance: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "start-dbaas-opensearch-maintenance")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("StartDBAASOpensearchMaintenance: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("StartDBAASOpensearchMaintenance: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("StartDBAASOpensearchMaintenance: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type CreateDBAASOpensearchUserRequest struct {
	Username DBAASUserUsername `json:"username" validate:"required,gte=1,lte=64"`
}

func (c Client) CreateDBAASOpensearchUser(ctx context.Context, serviceName string, req CreateDBAASOpensearchUserRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-opensearch/%v/user", serviceName)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASOpensearchUser: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASOpensearchUser: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateDBAASOpensearchUser: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateDBAASOpensearchUser: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-dbaas-opensearch-user")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASOpensearchUser: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateDBAASOpensearchUser: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateDBAASOpensearchUser: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) DeleteDBAASOpensearchUser(ctx context.Context, serviceName string, username string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-opensearch/%v/user/%v", serviceName, username)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASOpensearchUser: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASOpensearchUser: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASOpensearchUser: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-dbaas-opensearch-user")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASOpensearchUser: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteDBAASOpensearchUser: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteDBAASOpensearchUser: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ResetDBAASOpensearchUserPasswordRequest struct {
	Password DBAASUserPassword `json:"password,omitempty" validate:"omitempty,gte=8,lte=256"`
}

// If no password is provided one will be generated automatically.
func (c Client) ResetDBAASOpensearchUserPassword(ctx context.Context, serviceName string, username string, req ResetDBAASOpensearchUserPasswordRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-opensearch/%v/user/%v/password/reset", serviceName, username)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("ResetDBAASOpensearchUserPassword: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("ResetDBAASOpensearchUserPassword: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ResetDBAASOpensearchUserPassword: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ResetDBAASOpensearchUserPassword: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reset-dbaas-opensearch-user-password")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ResetDBAASOpensearchUserPassword: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ResetDBAASOpensearchUserPassword: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ResetDBAASOpensearchUserPassword: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) RevealDBAASOpensearchUserPassword(ctx context.Context, serviceName string, username string) (*DBAASUserOpensearchSecrets, error) {
	path := fmt.Sprintf("/dbaas-opensearch/%v/user/%v/password/reveal", serviceName, username)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("RevealDBAASOpensearchUserPassword: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("RevealDBAASOpensearchUserPassword: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("RevealDBAASOpensearchUserPassword: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reveal-dbaas-opensearch-user-password")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("RevealDBAASOpensearchUserPassword: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("RevealDBAASOpensearchUserPassword: http response: %w", err)
	}

	bodyresp := new(DBAASUserOpensearchSecrets)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("RevealDBAASOpensearchUserPassword: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) DeleteDBAASServicePG(ctx context.Context, name string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-postgres/%v", name)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASServicePG: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServicePG: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServicePG: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-dbaas-service-pg")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASServicePG: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServicePG: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServicePG: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Get a DBaaS PostgreSQL service
func (c Client) GetDBAASServicePG(ctx context.Context, name string) (*DBAASServicePG, error) {
	path := fmt.Sprintf("/dbaas-postgres/%v", name)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASServicePG: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASServicePG: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASServicePG: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-service-pg")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASServicePG: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASServicePG: http response: %w", err)
	}

	bodyresp := new(DBAASServicePG)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASServicePG: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type CreateDBAASServicePGRequestBackupSchedule struct {
	// The hour of day (in UTC) when backup for the service is started. New backup is only started if previous backup has already completed.
	BackupHour *int64 `json:"backup-hour,omitempty" validate:"omitempty,gte=0,lte=23"`
	// The minute of an hour when backup for the service is started. New backup is only started if previous backup has already completed.
	BackupMinute *int64 `json:"backup-minute,omitempty" validate:"omitempty,gte=0,lte=59"`
}

type CreateDBAASServicePGRequestIntegrationsType string

const (
	CreateDBAASServicePGRequestIntegrationsTypeReadReplica CreateDBAASServicePGRequestIntegrationsType = "read_replica"
)

type CreateDBAASServicePGRequestIntegrations struct {
	DestService DBAASServiceName `json:"dest-service,omitempty" validate:"omitempty,gte=0,lte=63"`
	// Integration settings
	Settings      map[string]any   `json:"settings,omitempty"`
	SourceService DBAASServiceName `json:"source-service,omitempty" validate:"omitempty,gte=0,lte=63"`
	// Integration type
	Type CreateDBAASServicePGRequestIntegrationsType `json:"type" validate:"required"`
}

type CreateDBAASServicePGRequestMaintenanceDow string

const (
	CreateDBAASServicePGRequestMaintenanceDowSaturday  CreateDBAASServicePGRequestMaintenanceDow = "saturday"
	CreateDBAASServicePGRequestMaintenanceDowTuesday   CreateDBAASServicePGRequestMaintenanceDow = "tuesday"
	CreateDBAASServicePGRequestMaintenanceDowNever     CreateDBAASServicePGRequestMaintenanceDow = "never"
	CreateDBAASServicePGRequestMaintenanceDowWednesday CreateDBAASServicePGRequestMaintenanceDow = "wednesday"
	CreateDBAASServicePGRequestMaintenanceDowSunday    CreateDBAASServicePGRequestMaintenanceDow = "sunday"
	CreateDBAASServicePGRequestMaintenanceDowFriday    CreateDBAASServicePGRequestMaintenanceDow = "friday"
	CreateDBAASServicePGRequestMaintenanceDowMonday    CreateDBAASServicePGRequestMaintenanceDow = "monday"
	CreateDBAASServicePGRequestMaintenanceDowThursday  CreateDBAASServicePGRequestMaintenanceDow = "thursday"
)

// Automatic maintenance settings
type CreateDBAASServicePGRequestMaintenance struct {
	// Day of week for installing updates
	Dow CreateDBAASServicePGRequestMaintenanceDow `json:"dow" validate:"required"`
	// Time for installing updates, UTC
	Time string `json:"time" validate:"required,gte=8,lte=8"`
}

// Migrate data from existing server
type CreateDBAASServicePGRequestMigration struct {
	// Database name for bootstrapping the initial connection
	Dbname string `json:"dbname,omitempty" validate:"omitempty,gte=1,lte=63"`
	// Hostname or IP address of the server where to migrate data from
	Host string `json:"host" validate:"required,gte=1,lte=255"`
	// Comma-separated list of databases, which should be ignored during migration (supported by MySQL only at the moment)
	IgnoreDbs string              `json:"ignore-dbs,omitempty" validate:"omitempty,gte=1,lte=2048"`
	Method    EnumMigrationMethod `json:"method,omitempty"`
	// Password for authentication with the server where to migrate data from
	Password string `json:"password,omitempty" validate:"omitempty,gte=1,lte=255"`
	// Port number of the server where to migrate data from
	Port int64 `json:"port" validate:"required,gte=1,lte=65535"`
	// The server where to migrate data from is secured with SSL
	SSL *bool `json:"ssl,omitempty"`
	// User name for authentication with the server where to migrate data from
	Username string `json:"username,omitempty" validate:"omitempty,gte=1,lte=255"`
}

type CreateDBAASServicePGRequest struct {
	// Custom password for admin user. Defaults to random string. This must be set only when a new service is being created.
	AdminPassword string `json:"admin-password,omitempty" validate:"omitempty,gte=8,lte=256"`
	// Custom username for admin user. This must be set only when a new service is being created.
	AdminUsername   string                                     `json:"admin-username,omitempty" validate:"omitempty,gte=1,lte=64"`
	BackupSchedule  *CreateDBAASServicePGRequestBackupSchedule `json:"backup-schedule,omitempty"`
	ForkFromService DBAASServiceName                           `json:"fork-from-service,omitempty" validate:"omitempty,gte=0,lte=63"`
	// Service integrations to be enabled when creating the service.
	Integrations []CreateDBAASServicePGRequestIntegrations `json:"integrations,omitempty"`
	// Allow incoming connections from CIDR address block, e.g. '10.20.0.0/16'
	IPFilter []string `json:"ip-filter,omitempty"`
	// Automatic maintenance settings
	Maintenance *CreateDBAASServicePGRequestMaintenance `json:"maintenance,omitempty"`
	// Migrate data from existing server
	Migration *CreateDBAASServicePGRequestMigration `json:"migration,omitempty"`
	// postgresql.conf configuration values
	PGSettings *JSONSchemaPG `json:"pg-settings,omitempty"`
	// System-wide settings for the pgaudit extension.
	PgauditSettings *JSONSchemaPgaudit `json:"pgaudit-settings,omitempty"`
	// System-wide settings for pgbouncer.
	PgbouncerSettings *JSONSchemaPgbouncer `json:"pgbouncer-settings,omitempty"`
	// System-wide settings for pglookout.
	PglookoutSettings *JSONSchemaPglookout `json:"pglookout-settings,omitempty"`
	// Subscription plan
	Plan string `json:"plan" validate:"required,gte=1,lte=128"`
	// ISO time of a backup to recover from for services that support arbitrary times
	RecoveryBackupTime string `json:"recovery-backup-time,omitempty" validate:"omitempty,gte=1"`
	// Percentage of total RAM that the database server uses for shared memory buffers. Valid range is 20-60 (float), which corresponds to 20% - 60%. This setting adjusts the shared_buffers configuration value.
	SharedBuffersPercentage int64                        `json:"shared-buffers-percentage,omitempty" validate:"omitempty,gte=20,lte=60"`
	SynchronousReplication  EnumPGSynchronousReplication `json:"synchronous-replication,omitempty"`
	// Service is protected against termination and powering off
	TerminationProtection *bool `json:"termination-protection,omitempty"`
	// System-wide settings for the timescaledb extension
	TimescaledbSettings *JSONSchemaTimescaledb `json:"timescaledb-settings,omitempty"`
	Variant             EnumPGVariant          `json:"variant,omitempty"`
	Version             DBAASPGTargetVersions  `json:"version,omitempty"`
	// Sets the maximum amount of memory to be used by a query operation (such as a sort or hash table) before writing to temporary disk files, in MB. Default is 1MB + 0.075% of total RAM (up to 32MB).
	WorkMem int64 `json:"work-mem,omitempty" validate:"omitempty,gte=1,lte=1024"`
}

func (c Client) CreateDBAASServicePG(ctx context.Context, name string, req CreateDBAASServicePGRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-postgres/%v", name)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASServicePG: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASServicePG: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateDBAASServicePG: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateDBAASServicePG: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-dbaas-service-pg")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASServicePG: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateDBAASServicePG: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateDBAASServicePG: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type UpdateDBAASServicePGRequestBackupSchedule struct {
	// The hour of day (in UTC) when backup for the service is started. New backup is only started if previous backup has already completed.
	BackupHour *int64 `json:"backup-hour,omitempty" validate:"omitempty,gte=0,lte=23"`
	// The minute of an hour when backup for the service is started. New backup is only started if previous backup has already completed.
	BackupMinute *int64 `json:"backup-minute,omitempty" validate:"omitempty,gte=0,lte=59"`
}

type UpdateDBAASServicePGRequestMaintenanceDow string

const (
	UpdateDBAASServicePGRequestMaintenanceDowSaturday  UpdateDBAASServicePGRequestMaintenanceDow = "saturday"
	UpdateDBAASServicePGRequestMaintenanceDowTuesday   UpdateDBAASServicePGRequestMaintenanceDow = "tuesday"
	UpdateDBAASServicePGRequestMaintenanceDowNever     UpdateDBAASServicePGRequestMaintenanceDow = "never"
	UpdateDBAASServicePGRequestMaintenanceDowWednesday UpdateDBAASServicePGRequestMaintenanceDow = "wednesday"
	UpdateDBAASServicePGRequestMaintenanceDowSunday    UpdateDBAASServicePGRequestMaintenanceDow = "sunday"
	UpdateDBAASServicePGRequestMaintenanceDowFriday    UpdateDBAASServicePGRequestMaintenanceDow = "friday"
	UpdateDBAASServicePGRequestMaintenanceDowMonday    UpdateDBAASServicePGRequestMaintenanceDow = "monday"
	UpdateDBAASServicePGRequestMaintenanceDowThursday  UpdateDBAASServicePGRequestMaintenanceDow = "thursday"
)

// Automatic maintenance settings
type UpdateDBAASServicePGRequestMaintenance struct {
	// Day of week for installing updates
	Dow UpdateDBAASServicePGRequestMaintenanceDow `json:"dow" validate:"required"`
	// Time for installing updates, UTC
	Time string `json:"time" validate:"required,gte=8,lte=8"`
}

// Migrate data from existing server
type UpdateDBAASServicePGRequestMigration struct {
	// Database name for bootstrapping the initial connection
	Dbname string `json:"dbname,omitempty" validate:"omitempty,gte=1,lte=63"`
	// Hostname or IP address of the server where to migrate data from
	Host string `json:"host" validate:"required,gte=1,lte=255"`
	// Comma-separated list of databases, which should be ignored during migration (supported by MySQL only at the moment)
	IgnoreDbs string              `json:"ignore-dbs,omitempty" validate:"omitempty,gte=1,lte=2048"`
	Method    EnumMigrationMethod `json:"method,omitempty"`
	// Password for authentication with the server where to migrate data from
	Password string `json:"password,omitempty" validate:"omitempty,gte=1,lte=255"`
	// Port number of the server where to migrate data from
	Port int64 `json:"port" validate:"required,gte=1,lte=65535"`
	// The server where to migrate data from is secured with SSL
	SSL *bool `json:"ssl,omitempty"`
	// User name for authentication with the server where to migrate data from
	Username string `json:"username,omitempty" validate:"omitempty,gte=1,lte=255"`
}

type UpdateDBAASServicePGRequest struct {
	BackupSchedule *UpdateDBAASServicePGRequestBackupSchedule `json:"backup-schedule,omitempty"`
	// Allow incoming connections from CIDR address block, e.g. '10.20.0.0/16'
	IPFilter []string `json:"ip-filter,omitempty"`
	// Automatic maintenance settings
	Maintenance *UpdateDBAASServicePGRequestMaintenance `json:"maintenance,omitempty"`
	// Migrate data from existing server
	Migration *UpdateDBAASServicePGRequestMigration `json:"migration,omitempty"`
	// postgresql.conf configuration values
	PGSettings *JSONSchemaPG `json:"pg-settings,omitempty"`
	// System-wide settings for the pgaudit extension.
	PgauditSettings *JSONSchemaPgaudit `json:"pgaudit-settings,omitempty"`
	// System-wide settings for pgbouncer.
	PgbouncerSettings *JSONSchemaPgbouncer `json:"pgbouncer-settings,omitempty"`
	// System-wide settings for pglookout.
	PglookoutSettings *JSONSchemaPglookout `json:"pglookout-settings,omitempty"`
	// Subscription plan
	Plan string `json:"plan,omitempty" validate:"omitempty,gte=1,lte=128"`
	// Percentage of total RAM that the database server uses for shared memory buffers. Valid range is 20-60 (float), which corresponds to 20% - 60%. This setting adjusts the shared_buffers configuration value.
	SharedBuffersPercentage int64                        `json:"shared-buffers-percentage,omitempty" validate:"omitempty,gte=20,lte=60"`
	SynchronousReplication  EnumPGSynchronousReplication `json:"synchronous-replication,omitempty"`
	// Service is protected against termination and powering off
	TerminationProtection *bool `json:"termination-protection,omitempty"`
	// System-wide settings for the timescaledb extension
	TimescaledbSettings *JSONSchemaTimescaledb `json:"timescaledb-settings,omitempty"`
	Variant             EnumPGVariant          `json:"variant,omitempty"`
	// Version
	Version string `json:"version,omitempty"`
	// Sets the maximum amount of memory to be used by a query operation (such as a sort or hash table) before writing to temporary disk files, in MB. Default is 1MB + 0.075% of total RAM (up to 32MB).
	WorkMem int64 `json:"work-mem,omitempty" validate:"omitempty,gte=1,lte=1024"`
}

// Update a DBaaS PostgreSQL service
func (c Client) UpdateDBAASServicePG(ctx context.Context, name string, req UpdateDBAASServicePGRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-postgres/%v", name)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASServicePG: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASServicePG: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServicePG: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServicePG: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-dbaas-service-pg")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASServicePG: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServicePG: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServicePG: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) StartDBAASPGMaintenance(ctx context.Context, name string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-postgres/%v/maintenance/start", name)

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("StartDBAASPGMaintenance: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("StartDBAASPGMaintenance: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("StartDBAASPGMaintenance: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "start-dbaas-pg-maintenance")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("StartDBAASPGMaintenance: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("StartDBAASPGMaintenance: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("StartDBAASPGMaintenance: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) StopDBAASPGMigration(ctx context.Context, name string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-postgres/%v/migration/stop", name)

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("StopDBAASPGMigration: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("StopDBAASPGMigration: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("StopDBAASPGMigration: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "stop-dbaas-pg-migration")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("StopDBAASPGMigration: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("StopDBAASPGMigration: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("StopDBAASPGMigration: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type CreateDBAASPGConnectionPoolRequest struct {
	DatabaseName DBAASDatabaseName   `json:"database-name" validate:"required,gte=1,lte=40"`
	Mode         EnumPGPoolMode      `json:"mode,omitempty"`
	Name         DBAASPGPoolName     `json:"name" validate:"required,gte=1,lte=63"`
	Size         DBAASPGPoolSize     `json:"size,omitempty" validate:"omitempty,gte=1,lte=10000"`
	Username     DBAASPGPoolUsername `json:"username,omitempty" validate:"omitempty,gte=1,lte=64"`
}

// Create a DBaaS PostgreSQL connection pool
func (c Client) CreateDBAASPGConnectionPool(ctx context.Context, serviceName string, req CreateDBAASPGConnectionPoolRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-postgres/%v/connection-pool", serviceName)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASPGConnectionPool: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASPGConnectionPool: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateDBAASPGConnectionPool: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateDBAASPGConnectionPool: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-dbaas-pg-connection-pool")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASPGConnectionPool: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateDBAASPGConnectionPool: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateDBAASPGConnectionPool: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Delete a DBaaS PostgreSQL connection pool
func (c Client) DeleteDBAASPGConnectionPool(ctx context.Context, serviceName string, connectionPoolName string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-postgres/%v/connection-pool/%v", serviceName, connectionPoolName)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASPGConnectionPool: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASPGConnectionPool: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASPGConnectionPool: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-dbaas-pg-connection-pool")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASPGConnectionPool: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteDBAASPGConnectionPool: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteDBAASPGConnectionPool: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type UpdateDBAASPGConnectionPoolRequest struct {
	DatabaseName DBAASDatabaseName   `json:"database-name,omitempty" validate:"omitempty,gte=1,lte=40"`
	Mode         EnumPGPoolMode      `json:"mode,omitempty"`
	Size         DBAASPGPoolSize     `json:"size,omitempty" validate:"omitempty,gte=1,lte=10000"`
	Username     DBAASPGPoolUsername `json:"username,omitempty" validate:"omitempty,gte=1,lte=64"`
}

// Update a DBaaS PostgreSQL connection pool
func (c Client) UpdateDBAASPGConnectionPool(ctx context.Context, serviceName string, connectionPoolName string, req UpdateDBAASPGConnectionPoolRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-postgres/%v/connection-pool/%v", serviceName, connectionPoolName)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASPGConnectionPool: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASPGConnectionPool: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASPGConnectionPool: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASPGConnectionPool: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-dbaas-pg-connection-pool")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASPGConnectionPool: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateDBAASPGConnectionPool: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateDBAASPGConnectionPool: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type CreateDBAASPGDatabaseRequest struct {
	DatabaseName DBAASDatabaseName `json:"database-name" validate:"required,gte=1,lte=40"`
	// Default string sort order (LC_COLLATE) for PostgreSQL database
	LCCollate string `json:"lc-collate,omitempty" validate:"omitempty,lte=128"`
	// Default character classification (LC_CTYPE) for PostgreSQL database
	LCCtype string `json:"lc-ctype,omitempty" validate:"omitempty,lte=128"`
}

func (c Client) CreateDBAASPGDatabase(ctx context.Context, serviceName string, req CreateDBAASPGDatabaseRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-postgres/%v/database", serviceName)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASPGDatabase: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASPGDatabase: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateDBAASPGDatabase: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateDBAASPGDatabase: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-dbaas-pg-database")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASPGDatabase: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateDBAASPGDatabase: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateDBAASPGDatabase: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) DeleteDBAASPGDatabase(ctx context.Context, serviceName string, databaseName string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-postgres/%v/database/%v", serviceName, databaseName)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASPGDatabase: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASPGDatabase: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASPGDatabase: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-dbaas-pg-database")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASPGDatabase: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteDBAASPGDatabase: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteDBAASPGDatabase: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type CreateDBAASPostgresUserRequest struct {
	AllowReplication *bool             `json:"allow-replication,omitempty"`
	Username         DBAASUserUsername `json:"username" validate:"required,gte=1,lte=64"`
}

func (c Client) CreateDBAASPostgresUser(ctx context.Context, serviceName string, req CreateDBAASPostgresUserRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-postgres/%v/user", serviceName)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASPostgresUser: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASPostgresUser: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateDBAASPostgresUser: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateDBAASPostgresUser: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-dbaas-postgres-user")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASPostgresUser: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateDBAASPostgresUser: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateDBAASPostgresUser: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) DeleteDBAASPostgresUser(ctx context.Context, serviceName string, username string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-postgres/%v/user/%v", serviceName, username)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASPostgresUser: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASPostgresUser: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASPostgresUser: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-dbaas-postgres-user")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASPostgresUser: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteDBAASPostgresUser: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteDBAASPostgresUser: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type UpdateDBAASPostgresAllowReplicationRequest struct {
	AllowReplication *bool `json:"allow-replication,omitempty"`
}

func (c Client) UpdateDBAASPostgresAllowReplication(ctx context.Context, serviceName string, username string, req UpdateDBAASPostgresAllowReplicationRequest) (*DBAASPostgresUsers, error) {
	path := fmt.Sprintf("/dbaas-postgres/%v/user/%v/allow-replication", serviceName, username)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASPostgresAllowReplication: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASPostgresAllowReplication: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASPostgresAllowReplication: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASPostgresAllowReplication: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-dbaas-postgres-allow-replication")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASPostgresAllowReplication: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateDBAASPostgresAllowReplication: http response: %w", err)
	}

	bodyresp := new(DBAASPostgresUsers)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateDBAASPostgresAllowReplication: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ResetDBAASPostgresUserPasswordRequest struct {
	Password DBAASUserPassword `json:"password,omitempty" validate:"omitempty,gte=8,lte=256"`
}

// If no password is provided one will be generated automatically.
func (c Client) ResetDBAASPostgresUserPassword(ctx context.Context, serviceName string, username string, req ResetDBAASPostgresUserPasswordRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-postgres/%v/user/%v/password/reset", serviceName, username)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("ResetDBAASPostgresUserPassword: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("ResetDBAASPostgresUserPassword: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ResetDBAASPostgresUserPassword: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ResetDBAASPostgresUserPassword: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reset-dbaas-postgres-user-password")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ResetDBAASPostgresUserPassword: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ResetDBAASPostgresUserPassword: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ResetDBAASPostgresUserPassword: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) RevealDBAASPostgresUserPassword(ctx context.Context, serviceName string, username string) (*DBAASUserPostgresSecrets, error) {
	path := fmt.Sprintf("/dbaas-postgres/%v/user/%v/password/reveal", serviceName, username)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("RevealDBAASPostgresUserPassword: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("RevealDBAASPostgresUserPassword: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("RevealDBAASPostgresUserPassword: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reveal-dbaas-postgres-user-password")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("RevealDBAASPostgresUserPassword: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("RevealDBAASPostgresUserPassword: http response: %w", err)
	}

	bodyresp := new(DBAASUserPostgresSecrets)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("RevealDBAASPostgresUserPassword: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type CreateDBAASPGUpgradeCheckRequest struct {
	TargetVersion DBAASPGTargetVersions `json:"target-version" validate:"required"`
}

// Check whether you can upgrade Postgres service to a newer version
func (c Client) CreateDBAASPGUpgradeCheck(ctx context.Context, service string, req CreateDBAASPGUpgradeCheckRequest) (*DBAASTask, error) {
	path := fmt.Sprintf("/dbaas-postgres/%v/upgrade-check", service)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASPGUpgradeCheck: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASPGUpgradeCheck: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateDBAASPGUpgradeCheck: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateDBAASPGUpgradeCheck: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-dbaas-pg-upgrade-check")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASPGUpgradeCheck: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateDBAASPGUpgradeCheck: http response: %w", err)
	}

	bodyresp := new(DBAASTask)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateDBAASPGUpgradeCheck: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ListDBAASServicesResponse struct {
	DBAASServices []DBAASServiceCommon `json:"dbaas-services,omitempty"`
}

// FindDBAASServiceCommon attempts to find an DBAASServiceCommon by name.
func (l ListDBAASServicesResponse) FindDBAASServiceCommon(name string) (DBAASServiceCommon, error) {
	var result []DBAASServiceCommon
	for i, elem := range l.DBAASServices {
		if string(elem.Name) == name {
			result = append(result, l.DBAASServices[i])
		}
	}
	if len(result) == 1 {
		return result[0], nil
	}

	if len(result) > 1 {
		return DBAASServiceCommon{}, fmt.Errorf("%q too many found in ListDBAASServicesResponse: %w", name, ErrConflict)
	}

	return DBAASServiceCommon{}, fmt.Errorf("%q not found in ListDBAASServicesResponse: %w", name, ErrNotFound)
}

// List DBaaS services
func (c Client) ListDBAASServices(ctx context.Context) (*ListDBAASServicesResponse, error) {
	path := "/dbaas-service"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListDBAASServices: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListDBAASServices: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListDBAASServices: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-dbaas-services")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListDBAASServices: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListDBAASServices: http response: %w", err)
	}

	bodyresp := new(ListDBAASServicesResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListDBAASServices: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type GetDBAASServiceLogsRequest struct {
	// How many log entries to receive at most, up to 500 (default: 100)
	Limit int64 `json:"limit,omitempty" validate:"omitempty,gte=1,lte=500"`
	// Opaque offset identifier
	Offset    string        `json:"offset,omitempty"`
	SortOrder EnumSortOrder `json:"sort-order,omitempty"`
}

// Get logs of DBaaS service
func (c Client) GetDBAASServiceLogs(ctx context.Context, serviceName string, req GetDBAASServiceLogsRequest) (*DBAASServiceLogs, error) {
	path := fmt.Sprintf("/dbaas-service-logs/%v", serviceName)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASServiceLogs: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASServiceLogs: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceLogs: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceLogs: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-service-logs")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASServiceLogs: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceLogs: http response: %w", err)
	}

	bodyresp := new(DBAASServiceLogs)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceLogs: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type GetDBAASServiceMetricsResponse struct {
	Metrics map[string]any `json:"metrics,omitempty"`
}

type GetDBAASServiceMetricsRequestPeriod string

const (
	GetDBAASServiceMetricsRequestPeriodHour  GetDBAASServiceMetricsRequestPeriod = "hour"
	GetDBAASServiceMetricsRequestPeriodWeek  GetDBAASServiceMetricsRequestPeriod = "week"
	GetDBAASServiceMetricsRequestPeriodYear  GetDBAASServiceMetricsRequestPeriod = "year"
	GetDBAASServiceMetricsRequestPeriodMonth GetDBAASServiceMetricsRequestPeriod = "month"
	GetDBAASServiceMetricsRequestPeriodDay   GetDBAASServiceMetricsRequestPeriod = "day"
)

type GetDBAASServiceMetricsRequest struct {
	// Metrics time period (default: hour)
	Period GetDBAASServiceMetricsRequestPeriod `json:"period,omitempty"`
}

// Get metrics of DBaaS service
func (c Client) GetDBAASServiceMetrics(ctx context.Context, serviceName string, req GetDBAASServiceMetricsRequest) (*GetDBAASServiceMetricsResponse, error) {
	path := fmt.Sprintf("/dbaas-service-metrics/%v", serviceName)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASServiceMetrics: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASServiceMetrics: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceMetrics: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceMetrics: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-service-metrics")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASServiceMetrics: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceMetrics: http response: %w", err)
	}

	bodyresp := new(GetDBAASServiceMetricsResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceMetrics: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ListDBAASServiceTypesResponse struct {
	DBAASServiceTypes []DBAASServiceType `json:"dbaas-service-types,omitempty"`
}

// FindDBAASServiceType attempts to find an DBAASServiceType by name.
func (l ListDBAASServiceTypesResponse) FindDBAASServiceType(name string) (DBAASServiceType, error) {
	var result []DBAASServiceType
	for i, elem := range l.DBAASServiceTypes {
		if string(elem.Name) == name {
			result = append(result, l.DBAASServiceTypes[i])
		}
	}
	if len(result) == 1 {
		return result[0], nil
	}

	if len(result) > 1 {
		return DBAASServiceType{}, fmt.Errorf("%q too many found in ListDBAASServiceTypesResponse: %w", name, ErrConflict)
	}

	return DBAASServiceType{}, fmt.Errorf("%q not found in ListDBAASServiceTypesResponse: %w", name, ErrNotFound)
}

// List available service types for DBaaS
func (c Client) ListDBAASServiceTypes(ctx context.Context) (*ListDBAASServiceTypesResponse, error) {
	path := "/dbaas-service-type"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListDBAASServiceTypes: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListDBAASServiceTypes: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListDBAASServiceTypes: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-dbaas-service-types")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListDBAASServiceTypes: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListDBAASServiceTypes: http response: %w", err)
	}

	bodyresp := new(ListDBAASServiceTypesResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListDBAASServiceTypes: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Get a DBaaS service type
func (c Client) GetDBAASServiceType(ctx context.Context, serviceTypeName string) (*DBAASServiceType, error) {
	path := fmt.Sprintf("/dbaas-service-type/%v", serviceTypeName)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASServiceType: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceType: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceType: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-service-type")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASServiceType: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceType: http response: %w", err)
	}

	bodyresp := new(DBAASServiceType)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceType: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Delete a DBaaS service
func (c Client) DeleteDBAASService(ctx context.Context, name string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-service/%v", name)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASService: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASService: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASService: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-dbaas-service")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASService: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteDBAASService: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteDBAASService: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// ClickHouse configuration values
type GetDBAASSettingsClickhouseResponseSettingsClickhouse struct {
	AdditionalProperties *bool          `json:"additionalProperties,omitempty"`
	Properties           map[string]any `json:"properties,omitempty"`
	Title                string         `json:"title,omitempty"`
	Type                 string         `json:"type,omitempty"`
}

type GetDBAASSettingsClickhouseResponseSettings struct {
	// ClickHouse configuration values
	Clickhouse *GetDBAASSettingsClickhouseResponseSettingsClickhouse `json:"clickhouse,omitempty"`
}

type GetDBAASSettingsClickhouseResponse struct {
	Settings *GetDBAASSettingsClickhouseResponseSettings `json:"settings,omitempty"`
}

func (c Client) GetDBAASSettingsClickhouse(ctx context.Context) (*GetDBAASSettingsClickhouseResponse, error) {
	path := "/dbaas-settings-clickhouse"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsClickhouse: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsClickhouse: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsClickhouse: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-settings-clickhouse")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsClickhouse: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsClickhouse: http response: %w", err)
	}

	bodyresp := new(GetDBAASSettingsClickhouseResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsClickhouse: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Grafana configuration values
type GetDBAASSettingsGrafanaResponseSettingsGrafana struct {
	AdditionalProperties *bool          `json:"additionalProperties,omitempty"`
	Properties           map[string]any `json:"properties,omitempty"`
	Title                string         `json:"title,omitempty"`
	Type                 string         `json:"type,omitempty"`
}

type GetDBAASSettingsGrafanaResponseSettings struct {
	// Grafana configuration values
	Grafana *GetDBAASSettingsGrafanaResponseSettingsGrafana `json:"grafana,omitempty"`
}

type GetDBAASSettingsGrafanaResponse struct {
	Settings *GetDBAASSettingsGrafanaResponseSettings `json:"settings,omitempty"`
}

// Get DBaaS Grafana settings
func (c Client) GetDBAASSettingsGrafana(ctx context.Context) (*GetDBAASSettingsGrafanaResponse, error) {
	path := "/dbaas-settings-grafana"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsGrafana: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsGrafana: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsGrafana: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-settings-grafana")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsGrafana: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsGrafana: http response: %w", err)
	}

	bodyresp := new(GetDBAASSettingsGrafanaResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsGrafana: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Kafka broker configuration values
type GetDBAASSettingsKafkaResponseSettingsKafka struct {
	AdditionalProperties *bool          `json:"additionalProperties,omitempty"`
	Properties           map[string]any `json:"properties,omitempty"`
	Title                string         `json:"title,omitempty"`
	Type                 string         `json:"type,omitempty"`
}

// Kafka Connect configuration values
type GetDBAASSettingsKafkaResponseSettingsKafkaConnect struct {
	AdditionalProperties *bool          `json:"additionalProperties,omitempty"`
	Properties           map[string]any `json:"properties,omitempty"`
	Title                string         `json:"title,omitempty"`
	Type                 string         `json:"type,omitempty"`
}

// Kafka REST configuration
type GetDBAASSettingsKafkaResponseSettingsKafkaRest struct {
	AdditionalProperties *bool          `json:"additionalProperties,omitempty"`
	Properties           map[string]any `json:"properties,omitempty"`
	Title                string         `json:"title,omitempty"`
	Type                 string         `json:"type,omitempty"`
}

// Schema Registry configuration
type GetDBAASSettingsKafkaResponseSettingsSchemaRegistry struct {
	AdditionalProperties *bool          `json:"additionalProperties,omitempty"`
	Properties           map[string]any `json:"properties,omitempty"`
	Title                string         `json:"title,omitempty"`
	Type                 string         `json:"type,omitempty"`
}

type GetDBAASSettingsKafkaResponseSettings struct {
	// Kafka broker configuration values
	Kafka *GetDBAASSettingsKafkaResponseSettingsKafka `json:"kafka,omitempty"`
	// Kafka Connect configuration values
	KafkaConnect *GetDBAASSettingsKafkaResponseSettingsKafkaConnect `json:"kafka-connect,omitempty"`
	// Kafka REST configuration
	KafkaRest *GetDBAASSettingsKafkaResponseSettingsKafkaRest `json:"kafka-rest,omitempty"`
	// Schema Registry configuration
	SchemaRegistry *GetDBAASSettingsKafkaResponseSettingsSchemaRegistry `json:"schema-registry,omitempty"`
}

type GetDBAASSettingsKafkaResponse struct {
	Settings *GetDBAASSettingsKafkaResponseSettings `json:"settings,omitempty"`
}

// Get DBaaS Kafka settings
func (c Client) GetDBAASSettingsKafka(ctx context.Context) (*GetDBAASSettingsKafkaResponse, error) {
	path := "/dbaas-settings-kafka"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsKafka: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsKafka: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsKafka: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-settings-kafka")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsKafka: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsKafka: http response: %w", err)
	}

	bodyresp := new(GetDBAASSettingsKafkaResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsKafka: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// mysql.conf configuration values
type GetDBAASSettingsMysqlResponseSettingsMysql struct {
	AdditionalProperties *bool          `json:"additionalProperties,omitempty"`
	Properties           map[string]any `json:"properties,omitempty"`
	Title                string         `json:"title,omitempty"`
	Type                 string         `json:"type,omitempty"`
}

type GetDBAASSettingsMysqlResponseSettings struct {
	// mysql.conf configuration values
	Mysql *GetDBAASSettingsMysqlResponseSettingsMysql `json:"mysql,omitempty"`
}

type GetDBAASSettingsMysqlResponse struct {
	Settings *GetDBAASSettingsMysqlResponseSettings `json:"settings,omitempty"`
}

// Get DBaaS MySQL settings
func (c Client) GetDBAASSettingsMysql(ctx context.Context) (*GetDBAASSettingsMysqlResponse, error) {
	path := "/dbaas-settings-mysql"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsMysql: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsMysql: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsMysql: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-settings-mysql")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsMysql: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsMysql: http response: %w", err)
	}

	bodyresp := new(GetDBAASSettingsMysqlResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsMysql: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// OpenSearch configuration values
type GetDBAASSettingsOpensearchResponseSettingsOpensearch struct {
	AdditionalProperties *bool          `json:"additionalProperties,omitempty"`
	Properties           map[string]any `json:"properties,omitempty"`
	Title                string         `json:"title,omitempty"`
	Type                 string         `json:"type,omitempty"`
}

type GetDBAASSettingsOpensearchResponseSettings struct {
	// OpenSearch configuration values
	Opensearch *GetDBAASSettingsOpensearchResponseSettingsOpensearch `json:"opensearch,omitempty"`
}

type GetDBAASSettingsOpensearchResponse struct {
	Settings *GetDBAASSettingsOpensearchResponseSettings `json:"settings,omitempty"`
}

// Get DBaaS OpenSearch settings
func (c Client) GetDBAASSettingsOpensearch(ctx context.Context) (*GetDBAASSettingsOpensearchResponse, error) {
	path := "/dbaas-settings-opensearch"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsOpensearch: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsOpensearch: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsOpensearch: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-settings-opensearch")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsOpensearch: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsOpensearch: http response: %w", err)
	}

	bodyresp := new(GetDBAASSettingsOpensearchResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsOpensearch: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// postgresql.conf configuration values
type GetDBAASSettingsPGResponseSettingsPG struct {
	AdditionalProperties *bool          `json:"additionalProperties,omitempty"`
	Properties           map[string]any `json:"properties,omitempty"`
	Title                string         `json:"title,omitempty"`
	Type                 string         `json:"type,omitempty"`
}

// PGBouncer connection pooling settings
type GetDBAASSettingsPGResponseSettingsPgbouncer struct {
	AdditionalProperties *bool          `json:"additionalProperties,omitempty"`
	Properties           map[string]any `json:"properties,omitempty"`
	Title                string         `json:"title,omitempty"`
	Type                 string         `json:"type,omitempty"`
}

// PGLookout settings
type GetDBAASSettingsPGResponseSettingsPglookout struct {
	AdditionalProperties *bool          `json:"additionalProperties,omitempty"`
	Properties           map[string]any `json:"properties,omitempty"`
	Title                string         `json:"title,omitempty"`
	Type                 string         `json:"type,omitempty"`
}

// TimescaleDB extension configuration values
type GetDBAASSettingsPGResponseSettingsTimescaledb struct {
	AdditionalProperties *bool          `json:"additionalProperties,omitempty"`
	Properties           map[string]any `json:"properties,omitempty"`
	Title                string         `json:"title,omitempty"`
	Type                 string         `json:"type,omitempty"`
}

type GetDBAASSettingsPGResponseSettings struct {
	// postgresql.conf configuration values
	PG *GetDBAASSettingsPGResponseSettingsPG `json:"pg,omitempty"`
	// PGBouncer connection pooling settings
	Pgbouncer *GetDBAASSettingsPGResponseSettingsPgbouncer `json:"pgbouncer,omitempty"`
	// PGLookout settings
	Pglookout *GetDBAASSettingsPGResponseSettingsPglookout `json:"pglookout,omitempty"`
	// TimescaleDB extension configuration values
	Timescaledb *GetDBAASSettingsPGResponseSettingsTimescaledb `json:"timescaledb,omitempty"`
}

type GetDBAASSettingsPGResponse struct {
	Settings *GetDBAASSettingsPGResponseSettings `json:"settings,omitempty"`
}

// Get DBaaS PostgreSQL settings
func (c Client) GetDBAASSettingsPG(ctx context.Context) (*GetDBAASSettingsPGResponse, error) {
	path := "/dbaas-settings-pg"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsPG: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsPG: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsPG: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-settings-pg")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsPG: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsPG: http response: %w", err)
	}

	bodyresp := new(GetDBAASSettingsPGResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsPG: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Thanos configuration values
type GetDBAASSettingsThanosResponseSettingsThanos struct {
	AdditionalProperties *bool          `json:"additionalProperties,omitempty"`
	Properties           map[string]any `json:"properties,omitempty"`
	Title                string         `json:"title,omitempty"`
	Type                 string         `json:"type,omitempty"`
}

type GetDBAASSettingsThanosResponseSettings struct {
	// Thanos configuration values
	Thanos *GetDBAASSettingsThanosResponseSettingsThanos `json:"thanos,omitempty"`
}

type GetDBAASSettingsThanosResponse struct {
	Settings *GetDBAASSettingsThanosResponseSettings `json:"settings,omitempty"`
}

// Get DBaaS Thanos settings
func (c Client) GetDBAASSettingsThanos(ctx context.Context) (*GetDBAASSettingsThanosResponse, error) {
	path := "/dbaas-settings-thanos"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsThanos: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsThanos: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsThanos: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-settings-thanos")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsThanos: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsThanos: http response: %w", err)
	}

	bodyresp := new(GetDBAASSettingsThanosResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsThanos: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Valkey configuration values
type GetDBAASSettingsValkeyResponseSettingsValkey struct {
	AdditionalProperties *bool          `json:"additionalProperties,omitempty"`
	Properties           map[string]any `json:"properties,omitempty"`
	Title                string         `json:"title,omitempty"`
	Type                 string         `json:"type,omitempty"`
}

type GetDBAASSettingsValkeyResponseSettings struct {
	// Valkey configuration values
	Valkey *GetDBAASSettingsValkeyResponseSettingsValkey `json:"valkey,omitempty"`
}

type GetDBAASSettingsValkeyResponse struct {
	Settings *GetDBAASSettingsValkeyResponseSettings `json:"settings,omitempty"`
}

// Returns the default settings for Valkey.
func (c Client) GetDBAASSettingsValkey(ctx context.Context) (*GetDBAASSettingsValkeyResponse, error) {
	path := "/dbaas-settings-valkey"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsValkey: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsValkey: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsValkey: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-settings-valkey")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsValkey: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsValkey: http response: %w", err)
	}

	bodyresp := new(GetDBAASSettingsValkeyResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsValkey: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type CreateDBAASTaskMigrationCheckRequest struct {
	// Comma-separated list of databases, which should be ignored during migration (supported by MySQL only at the moment)
	IgnoreDbs string              `json:"ignore-dbs,omitempty" validate:"omitempty,gte=1,lte=2048"`
	Method    EnumMigrationMethod `json:"method,omitempty"`
	// Service URI of the source MySQL or PostgreSQL database with admin credentials.
	SourceServiceURI string `json:"source-service-uri" validate:"required,gte=1,lte=512"`
}

// Create a DBaaS task to check migration
func (c Client) CreateDBAASTaskMigrationCheck(ctx context.Context, service string, req CreateDBAASTaskMigrationCheckRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-task-migration-check/%v", service)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASTaskMigrationCheck: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASTaskMigrationCheck: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateDBAASTaskMigrationCheck: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateDBAASTaskMigrationCheck: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-dbaas-task-migration-check")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASTaskMigrationCheck: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateDBAASTaskMigrationCheck: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateDBAASTaskMigrationCheck: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Get a DBaaS task
func (c Client) GetDBAASTask(ctx context.Context, service string, id UUID) (*DBAASTask, error) {
	path := fmt.Sprintf("/dbaas-task/%v/%v", service, id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASTask: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASTask: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASTask: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-task")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASTask: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASTask: http response: %w", err)
	}

	bodyresp := new(DBAASTask)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASTask: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) DeleteDBAASServiceThanos(ctx context.Context, name string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-thanos/%v", name)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceThanos: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceThanos: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceThanos: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-dbaas-service-thanos")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceThanos: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceThanos: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceThanos: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Get a DBaaS Thanos service
func (c Client) GetDBAASServiceThanos(ctx context.Context, name string) (*DBAASServiceThanos, error) {
	path := fmt.Sprintf("/dbaas-thanos/%v", name)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASServiceThanos: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceThanos: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceThanos: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-service-thanos")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASServiceThanos: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceThanos: http response: %w", err)
	}

	bodyresp := new(DBAASServiceThanos)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceThanos: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type CreateDBAASServiceThanosRequestMaintenanceDow string

const (
	CreateDBAASServiceThanosRequestMaintenanceDowSaturday  CreateDBAASServiceThanosRequestMaintenanceDow = "saturday"
	CreateDBAASServiceThanosRequestMaintenanceDowTuesday   CreateDBAASServiceThanosRequestMaintenanceDow = "tuesday"
	CreateDBAASServiceThanosRequestMaintenanceDowNever     CreateDBAASServiceThanosRequestMaintenanceDow = "never"
	CreateDBAASServiceThanosRequestMaintenanceDowWednesday CreateDBAASServiceThanosRequestMaintenanceDow = "wednesday"
	CreateDBAASServiceThanosRequestMaintenanceDowSunday    CreateDBAASServiceThanosRequestMaintenanceDow = "sunday"
	CreateDBAASServiceThanosRequestMaintenanceDowFriday    CreateDBAASServiceThanosRequestMaintenanceDow = "friday"
	CreateDBAASServiceThanosRequestMaintenanceDowMonday    CreateDBAASServiceThanosRequestMaintenanceDow = "monday"
	CreateDBAASServiceThanosRequestMaintenanceDowThursday  CreateDBAASServiceThanosRequestMaintenanceDow = "thursday"
)

// Automatic maintenance settings
type CreateDBAASServiceThanosRequestMaintenance struct {
	// Day of week for installing updates
	Dow CreateDBAASServiceThanosRequestMaintenanceDow `json:"dow" validate:"required"`
	// Time for installing updates, UTC
	Time string `json:"time" validate:"required,gte=8,lte=8"`
}

type CreateDBAASServiceThanosRequest struct {
	// Allowed CIDR address blocks for incoming connections
	IPFilter []string `json:"ip-filter,omitempty"`
	// Automatic maintenance settings
	Maintenance *CreateDBAASServiceThanosRequestMaintenance `json:"maintenance,omitempty"`
	// Subscription plan
	Plan string `json:"plan" validate:"required,gte=1,lte=128"`
	// Service is protected against termination and powering off
	TerminationProtection *bool `json:"termination-protection,omitempty"`
	// Thanos settings
	ThanosSettings *JSONSchemaThanos `json:"thanos-settings,omitempty"`
}

// Create a DBaaS Thanos service
func (c Client) CreateDBAASServiceThanos(ctx context.Context, name string, req CreateDBAASServiceThanosRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-thanos/%v", name)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceThanos: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceThanos: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceThanos: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceThanos: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-dbaas-service-thanos")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceThanos: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceThanos: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceThanos: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type UpdateDBAASServiceThanosRequestMaintenanceDow string

const (
	UpdateDBAASServiceThanosRequestMaintenanceDowSaturday  UpdateDBAASServiceThanosRequestMaintenanceDow = "saturday"
	UpdateDBAASServiceThanosRequestMaintenanceDowTuesday   UpdateDBAASServiceThanosRequestMaintenanceDow = "tuesday"
	UpdateDBAASServiceThanosRequestMaintenanceDowNever     UpdateDBAASServiceThanosRequestMaintenanceDow = "never"
	UpdateDBAASServiceThanosRequestMaintenanceDowWednesday UpdateDBAASServiceThanosRequestMaintenanceDow = "wednesday"
	UpdateDBAASServiceThanosRequestMaintenanceDowSunday    UpdateDBAASServiceThanosRequestMaintenanceDow = "sunday"
	UpdateDBAASServiceThanosRequestMaintenanceDowFriday    UpdateDBAASServiceThanosRequestMaintenanceDow = "friday"
	UpdateDBAASServiceThanosRequestMaintenanceDowMonday    UpdateDBAASServiceThanosRequestMaintenanceDow = "monday"
	UpdateDBAASServiceThanosRequestMaintenanceDowThursday  UpdateDBAASServiceThanosRequestMaintenanceDow = "thursday"
)

// Automatic maintenance settings
type UpdateDBAASServiceThanosRequestMaintenance struct {
	// Day of week for installing updates
	Dow UpdateDBAASServiceThanosRequestMaintenanceDow `json:"dow" validate:"required"`
	// Time for installing updates, UTC
	Time string `json:"time" validate:"required,gte=8,lte=8"`
}

type UpdateDBAASServiceThanosRequest struct {
	// Allowed CIDR address blocks for incoming connections
	IPFilter []string `json:"ip-filter,omitempty"`
	// Automatic maintenance settings
	Maintenance *UpdateDBAASServiceThanosRequestMaintenance `json:"maintenance,omitempty"`
	// Subscription plan
	Plan string `json:"plan,omitempty" validate:"omitempty,gte=1,lte=128"`
	// Service is protected against termination and powering off
	TerminationProtection *bool `json:"termination-protection,omitempty"`
	// Thanos settings
	ThanosSettings *JSONSchemaThanos `json:"thanos-settings,omitempty"`
}

// Update a DBaaS Thanos service
func (c Client) UpdateDBAASServiceThanos(ctx context.Context, name string, req UpdateDBAASServiceThanosRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-thanos/%v", name)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceThanos: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceThanos: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceThanos: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceThanos: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-dbaas-service-thanos")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceThanos: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceThanos: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceThanos: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) StartDBAASThanosMaintenance(ctx context.Context, name string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-thanos/%v/maintenance/start", name)

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("StartDBAASThanosMaintenance: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("StartDBAASThanosMaintenance: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("StartDBAASThanosMaintenance: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "start-dbaas-thanos-maintenance")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("StartDBAASThanosMaintenance: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("StartDBAASThanosMaintenance: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("StartDBAASThanosMaintenance: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) RevealDBAASThanosUserPassword(ctx context.Context, serviceName string, username string) (*DBAASUserThanosSecrets, error) {
	path := fmt.Sprintf("/dbaas-thanos/%v/user/%v/password/reveal", serviceName, username)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("RevealDBAASThanosUserPassword: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("RevealDBAASThanosUserPassword: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("RevealDBAASThanosUserPassword: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reveal-dbaas-thanos-user-password")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("RevealDBAASThanosUserPassword: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("RevealDBAASThanosUserPassword: http response: %w", err)
	}

	bodyresp := new(DBAASUserThanosSecrets)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("RevealDBAASThanosUserPassword: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) DeleteDBAASServiceValkey(ctx context.Context, name string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-valkey/%v", name)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceValkey: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceValkey: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceValkey: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-dbaas-service-valkey")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceValkey: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceValkey: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceValkey: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Get a DBaaS Valkey service
func (c Client) GetDBAASServiceValkey(ctx context.Context, name string) (*DBAASServiceValkey, error) {
	path := fmt.Sprintf("/dbaas-valkey/%v", name)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASServiceValkey: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceValkey: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceValkey: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-service-valkey")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASServiceValkey: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceValkey: http response: %w", err)
	}

	bodyresp := new(DBAASServiceValkey)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceValkey: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type CreateDBAASServiceValkeyRequestMaintenanceDow string

const (
	CreateDBAASServiceValkeyRequestMaintenanceDowSaturday  CreateDBAASServiceValkeyRequestMaintenanceDow = "saturday"
	CreateDBAASServiceValkeyRequestMaintenanceDowTuesday   CreateDBAASServiceValkeyRequestMaintenanceDow = "tuesday"
	CreateDBAASServiceValkeyRequestMaintenanceDowNever     CreateDBAASServiceValkeyRequestMaintenanceDow = "never"
	CreateDBAASServiceValkeyRequestMaintenanceDowWednesday CreateDBAASServiceValkeyRequestMaintenanceDow = "wednesday"
	CreateDBAASServiceValkeyRequestMaintenanceDowSunday    CreateDBAASServiceValkeyRequestMaintenanceDow = "sunday"
	CreateDBAASServiceValkeyRequestMaintenanceDowFriday    CreateDBAASServiceValkeyRequestMaintenanceDow = "friday"
	CreateDBAASServiceValkeyRequestMaintenanceDowMonday    CreateDBAASServiceValkeyRequestMaintenanceDow = "monday"
	CreateDBAASServiceValkeyRequestMaintenanceDowThursday  CreateDBAASServiceValkeyRequestMaintenanceDow = "thursday"
)

// Automatic maintenance settings
type CreateDBAASServiceValkeyRequestMaintenance struct {
	// Day of week for installing updates
	Dow CreateDBAASServiceValkeyRequestMaintenanceDow `json:"dow" validate:"required"`
	// Time for installing updates, UTC
	Time string `json:"time" validate:"required,gte=8,lte=8"`
}

// Migrate data from existing server
type CreateDBAASServiceValkeyRequestMigration struct {
	// Database name for bootstrapping the initial connection
	Dbname string `json:"dbname,omitempty" validate:"omitempty,gte=1,lte=63"`
	// Hostname or IP address of the server where to migrate data from
	Host string `json:"host" validate:"required,gte=1,lte=255"`
	// Comma-separated list of databases, which should be ignored during migration (supported by MySQL only at the moment)
	IgnoreDbs string              `json:"ignore-dbs,omitempty" validate:"omitempty,gte=1,lte=2048"`
	Method    EnumMigrationMethod `json:"method,omitempty"`
	// Password for authentication with the server where to migrate data from
	Password string `json:"password,omitempty" validate:"omitempty,gte=1,lte=255"`
	// Port number of the server where to migrate data from
	Port int64 `json:"port" validate:"required,gte=1,lte=65535"`
	// The server where to migrate data from is secured with SSL
	SSL *bool `json:"ssl,omitempty"`
	// User name for authentication with the server where to migrate data from
	Username string `json:"username,omitempty" validate:"omitempty,gte=1,lte=255"`
}

type CreateDBAASServiceValkeyRequest struct {
	ForkFromService DBAASServiceName `json:"fork-from-service,omitempty" validate:"omitempty,gte=0,lte=63"`
	// Allow incoming connections from CIDR address block, e.g. '10.20.0.0/16'
	IPFilter []string `json:"ip-filter,omitempty"`
	// Automatic maintenance settings
	Maintenance *CreateDBAASServiceValkeyRequestMaintenance `json:"maintenance,omitempty"`
	// Migrate data from existing server
	Migration *CreateDBAASServiceValkeyRequestMigration `json:"migration,omitempty"`
	// Subscription plan
	Plan string `json:"plan" validate:"required,gte=1,lte=128"`
	// Name of a backup to recover from for services that support backup names
	RecoveryBackupName string `json:"recovery-backup-name,omitempty" validate:"omitempty,gte=1"`
	// Service is protected against termination and powering off
	TerminationProtection *bool `json:"termination-protection,omitempty"`
	// Valkey settings
	ValkeySettings *JSONSchemaValkey `json:"valkey-settings,omitempty"`
	// Valkey major version
	Version string `json:"version,omitempty" validate:"omitempty,gte=1"`
}

// Create a DBaaS Valkey service
func (c Client) CreateDBAASServiceValkey(ctx context.Context, name string, req CreateDBAASServiceValkeyRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-valkey/%v", name)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceValkey: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceValkey: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceValkey: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceValkey: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-dbaas-service-valkey")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceValkey: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceValkey: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceValkey: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type UpdateDBAASServiceValkeyRequestMaintenanceDow string

const (
	UpdateDBAASServiceValkeyRequestMaintenanceDowSaturday  UpdateDBAASServiceValkeyRequestMaintenanceDow = "saturday"
	UpdateDBAASServiceValkeyRequestMaintenanceDowTuesday   UpdateDBAASServiceValkeyRequestMaintenanceDow = "tuesday"
	UpdateDBAASServiceValkeyRequestMaintenanceDowNever     UpdateDBAASServiceValkeyRequestMaintenanceDow = "never"
	UpdateDBAASServiceValkeyRequestMaintenanceDowWednesday UpdateDBAASServiceValkeyRequestMaintenanceDow = "wednesday"
	UpdateDBAASServiceValkeyRequestMaintenanceDowSunday    UpdateDBAASServiceValkeyRequestMaintenanceDow = "sunday"
	UpdateDBAASServiceValkeyRequestMaintenanceDowFriday    UpdateDBAASServiceValkeyRequestMaintenanceDow = "friday"
	UpdateDBAASServiceValkeyRequestMaintenanceDowMonday    UpdateDBAASServiceValkeyRequestMaintenanceDow = "monday"
	UpdateDBAASServiceValkeyRequestMaintenanceDowThursday  UpdateDBAASServiceValkeyRequestMaintenanceDow = "thursday"
)

// Automatic maintenance settings
type UpdateDBAASServiceValkeyRequestMaintenance struct {
	// Day of week for installing updates
	Dow UpdateDBAASServiceValkeyRequestMaintenanceDow `json:"dow" validate:"required"`
	// Time for installing updates, UTC
	Time string `json:"time" validate:"required,gte=8,lte=8"`
}

// Migrate data from existing server
type UpdateDBAASServiceValkeyRequestMigration struct {
	// Database name for bootstrapping the initial connection
	Dbname string `json:"dbname,omitempty" validate:"omitempty,gte=1,lte=63"`
	// Hostname or IP address of the server where to migrate data from
	Host string `json:"host" validate:"required,gte=1,lte=255"`
	// Comma-separated list of databases, which should be ignored during migration (supported by MySQL only at the moment)
	IgnoreDbs string              `json:"ignore-dbs,omitempty" validate:"omitempty,gte=1,lte=2048"`
	Method    EnumMigrationMethod `json:"method,omitempty"`
	// Password for authentication with the server where to migrate data from
	Password string `json:"password,omitempty" validate:"omitempty,gte=1,lte=255"`
	// Port number of the server where to migrate data from
	Port int64 `json:"port" validate:"required,gte=1,lte=65535"`
	// The server where to migrate data from is secured with SSL
	SSL *bool `json:"ssl,omitempty"`
	// User name for authentication with the server where to migrate data from
	Username string `json:"username,omitempty" validate:"omitempty,gte=1,lte=255"`
}

type UpdateDBAASServiceValkeyRequest struct {
	// Allow incoming connections from CIDR address block, e.g. '10.20.0.0/16'
	IPFilter []string `json:"ip-filter,omitempty"`
	// Automatic maintenance settings
	Maintenance *UpdateDBAASServiceValkeyRequestMaintenance `json:"maintenance,omitempty"`
	// Migrate data from existing server
	Migration *UpdateDBAASServiceValkeyRequestMigration `json:"migration,omitempty"`
	// Subscription plan
	Plan string `json:"plan,omitempty" validate:"omitempty,gte=1,lte=128"`
	// Service is protected against termination and powering off
	TerminationProtection *bool `json:"termination-protection,omitempty"`
	// Valkey settings
	ValkeySettings *JSONSchemaValkey `json:"valkey-settings,omitempty"`
	// Valkey major version
	Version string `json:"version,omitempty" validate:"omitempty,gte=1"`
}

// Update a DBaaS Valkey service
func (c Client) UpdateDBAASServiceValkey(ctx context.Context, name string, req UpdateDBAASServiceValkeyRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-valkey/%v", name)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceValkey: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceValkey: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceValkey: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceValkey: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-dbaas-service-valkey")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceValkey: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceValkey: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceValkey: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) StartDBAASValkeyMaintenance(ctx context.Context, name string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-valkey/%v/maintenance/start", name)

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("StartDBAASValkeyMaintenance: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("StartDBAASValkeyMaintenance: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("StartDBAASValkeyMaintenance: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "start-dbaas-valkey-maintenance")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("StartDBAASValkeyMaintenance: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("StartDBAASValkeyMaintenance: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("StartDBAASValkeyMaintenance: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) StopDBAASValkeyMigration(ctx context.Context, name string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-valkey/%v/migration/stop", name)

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("StopDBAASValkeyMigration: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("StopDBAASValkeyMigration: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("StopDBAASValkeyMigration: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "stop-dbaas-valkey-migration")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("StopDBAASValkeyMigration: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("StopDBAASValkeyMigration: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("StopDBAASValkeyMigration: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) ListDBAASValkeyUsers(ctx context.Context, serviceName string) (*DBAASValkeyUsers, error) {
	path := fmt.Sprintf("/dbaas-valkey/%v/user", serviceName)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListDBAASValkeyUsers: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListDBAASValkeyUsers: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListDBAASValkeyUsers: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-dbaas-valkey-users")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListDBAASValkeyUsers: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListDBAASValkeyUsers: http response: %w", err)
	}

	bodyresp := new(DBAASValkeyUsers)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListDBAASValkeyUsers: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type CreateDBAASValkeyUserRequest struct {
	AccessControl *DBAASValkeyUserAccessControl `json:"access-control,omitempty"`
	Username      DBAASUserUsername             `json:"username" validate:"required,gte=1,lte=64"`
}

func (c Client) CreateDBAASValkeyUser(ctx context.Context, serviceName string, req CreateDBAASValkeyUserRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-valkey/%v/user", serviceName)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASValkeyUser: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASValkeyUser: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateDBAASValkeyUser: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateDBAASValkeyUser: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-dbaas-valkey-user")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASValkeyUser: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateDBAASValkeyUser: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateDBAASValkeyUser: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) DeleteDBAASValkeyUser(ctx context.Context, serviceName string, username string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-valkey/%v/user/%v", serviceName, username)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASValkeyUser: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASValkeyUser: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASValkeyUser: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-dbaas-valkey-user")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASValkeyUser: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteDBAASValkeyUser: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteDBAASValkeyUser: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type UpdateDBAASValkeyUserAccessControlRequest struct {
	AccessControl *DBAASValkeyUserAccessControl `json:"access-control,omitempty"`
}

func (c Client) UpdateDBAASValkeyUserAccessControl(ctx context.Context, serviceName string, username string, req UpdateDBAASValkeyUserAccessControlRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-valkey/%v/user/%v", serviceName, username)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASValkeyUserAccessControl: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASValkeyUserAccessControl: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASValkeyUserAccessControl: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASValkeyUserAccessControl: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-dbaas-valkey-user-access-control")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASValkeyUserAccessControl: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateDBAASValkeyUserAccessControl: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateDBAASValkeyUserAccessControl: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ResetDBAASValkeyUserPasswordRequest struct {
	Password DBAASUserPassword `json:"password,omitempty" validate:"omitempty,gte=8,lte=256"`
}

// If no password is provided one will be generated automatically.
func (c Client) ResetDBAASValkeyUserPassword(ctx context.Context, serviceName string, username string, req ResetDBAASValkeyUserPasswordRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-valkey/%v/user/%v/password/reset", serviceName, username)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("ResetDBAASValkeyUserPassword: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("ResetDBAASValkeyUserPassword: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ResetDBAASValkeyUserPassword: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ResetDBAASValkeyUserPassword: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reset-dbaas-valkey-user-password")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ResetDBAASValkeyUserPassword: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ResetDBAASValkeyUserPassword: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ResetDBAASValkeyUserPassword: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) RevealDBAASValkeyUserPassword(ctx context.Context, serviceName string, username string) (*DBAASUserValkeySecrets, error) {
	path := fmt.Sprintf("/dbaas-valkey/%v/user/%v/password/reveal", serviceName, username)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("RevealDBAASValkeyUserPassword: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("RevealDBAASValkeyUserPassword: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("RevealDBAASValkeyUserPassword: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reveal-dbaas-valkey-user-password")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("RevealDBAASValkeyUserPassword: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("RevealDBAASValkeyUserPassword: http response: %w", err)
	}

	bodyresp := new(DBAASUserValkeySecrets)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("RevealDBAASValkeyUserPassword: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ListDeployTargetsResponse struct {
	DeployTargets []DeployTarget `json:"deploy-targets,omitempty"`
}

// FindDeployTarget attempts to find an DeployTarget by nameOrID.
func (l ListDeployTargetsResponse) FindDeployTarget(nameOrID string) (DeployTarget, error) {
	var result []DeployTarget
	for i, elem := range l.DeployTargets {
		if string(elem.Name) == nameOrID || string(elem.ID) == nameOrID {
			result = append(result, l.DeployTargets[i])
		}
	}
	if len(result) == 1 {
		return result[0], nil
	}

	if len(result) > 1 {
		return DeployTarget{}, fmt.Errorf("%q too many found in ListDeployTargetsResponse: %w", nameOrID, ErrConflict)
	}

	return DeployTarget{}, fmt.Errorf("%q not found in ListDeployTargetsResponse: %w", nameOrID, ErrNotFound)
}

// List Deploy Targets
func (c Client) ListDeployTargets(ctx context.Context) (*ListDeployTargetsResponse, error) {
	path := "/deploy-target"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListDeployTargets: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListDeployTargets: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListDeployTargets: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-deploy-targets")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListDeployTargets: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListDeployTargets: http response: %w", err)
	}

	bodyresp := new(ListDeployTargetsResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListDeployTargets: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Retrieve Deploy Target details
func (c Client) GetDeployTarget(ctx context.Context, id UUID) (*DeployTarget, error) {
	path := fmt.Sprintf("/deploy-target/%v", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDeployTarget: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDeployTarget: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDeployTarget: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-deploy-target")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDeployTarget: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDeployTarget: http response: %w", err)
	}

	bodyresp := new(DeployTarget)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDeployTarget: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ListDNSDomainsResponse struct {
	DNSDomains []DNSDomain `json:"dns-domains,omitempty"`
}

// FindDNSDomain attempts to find an DNSDomain by idOrUnicodeName.
func (l ListDNSDomainsResponse) FindDNSDomain(idOrUnicodeName string) (DNSDomain, error) {
	var result []DNSDomain
	for i, elem := range l.DNSDomains {
		if string(elem.ID) == idOrUnicodeName || string(elem.UnicodeName) == idOrUnicodeName {
			result = append(result, l.DNSDomains[i])
		}
	}
	if len(result) == 1 {
		return result[0], nil
	}

	if len(result) > 1 {
		return DNSDomain{}, fmt.Errorf("%q too many found in ListDNSDomainsResponse: %w", idOrUnicodeName, ErrConflict)
	}

	return DNSDomain{}, fmt.Errorf("%q not found in ListDNSDomainsResponse: %w", idOrUnicodeName, ErrNotFound)
}

// List DNS domains
func (c Client) ListDNSDomains(ctx context.Context) (*ListDNSDomainsResponse, error) {
	path := "/dns-domain"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListDNSDomains: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListDNSDomains: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListDNSDomains: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-dns-domains")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListDNSDomains: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListDNSDomains: http response: %w", err)
	}

	bodyresp := new(ListDNSDomainsResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListDNSDomains: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// DNS Domain
type CreateDNSDomainRequest struct {
	// Domain name
	UnicodeName string `json:"unicode-name,omitempty"`
}

// Create DNS domain
func (c Client) CreateDNSDomain(ctx context.Context, req CreateDNSDomainRequest) (*Operation, error) {
	path := "/dns-domain"

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateDNSDomain: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateDNSDomain: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateDNSDomain: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateDNSDomain: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-dns-domain")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateDNSDomain: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateDNSDomain: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateDNSDomain: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ListDNSDomainRecordsResponse struct {
	DNSDomainRecords []DNSDomainRecord `json:"dns-domain-records,omitempty"`
}

// FindDNSDomainRecord attempts to find an DNSDomainRecord by nameOrID.
func (l ListDNSDomainRecordsResponse) FindDNSDomainRecord(nameOrID string) (DNSDomainRecord, error) {
	var result []DNSDomainRecord
	for i, elem := range l.DNSDomainRecords {
		if string(elem.Name) == nameOrID || string(elem.ID) == nameOrID {
			result = append(result, l.DNSDomainRecords[i])
		}
	}
	if len(result) == 1 {
		return result[0], nil
	}

	if len(result) > 1 {
		return DNSDomainRecord{}, fmt.Errorf("%q too many found in ListDNSDomainRecordsResponse: %w", nameOrID, ErrConflict)
	}

	return DNSDomainRecord{}, fmt.Errorf("%q not found in ListDNSDomainRecordsResponse: %w", nameOrID, ErrNotFound)
}

// List DNS domain records
func (c Client) ListDNSDomainRecords(ctx context.Context, domainID UUID) (*ListDNSDomainRecordsResponse, error) {
	path := fmt.Sprintf("/dns-domain/%v/record", domainID)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListDNSDomainRecords: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListDNSDomainRecords: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListDNSDomainRecords: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-dns-domain-records")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListDNSDomainRecords: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListDNSDomainRecords: http response: %w", err)
	}

	bodyresp := new(ListDNSDomainRecordsResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListDNSDomainRecords: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type CreateDNSDomainRecordRequestType string

const (
	CreateDNSDomainRecordRequestTypeNS    CreateDNSDomainRecordRequestType = "NS"
	CreateDNSDomainRecordRequestTypeCAA   CreateDNSDomainRecordRequestType = "CAA"
	CreateDNSDomainRecordRequestTypeNAPTR CreateDNSDomainRecordRequestType = "NAPTR"
	CreateDNSDomainRecordRequestTypePOOL  CreateDNSDomainRecordRequestType = "POOL"
	CreateDNSDomainRecordRequestTypeA     CreateDNSDomainRecordRequestType = "A"
	CreateDNSDomainRecordRequestTypeHINFO CreateDNSDomainRecordRequestType = "HINFO"
	CreateDNSDomainRecordRequestTypeCNAME CreateDNSDomainRecordRequestType = "CNAME"
	CreateDNSDomainRecordRequestTypeSSHFP CreateDNSDomainRecordRequestType = "SSHFP"
	CreateDNSDomainRecordRequestTypeSRV   CreateDNSDomainRecordRequestType = "SRV"
	CreateDNSDomainRecordRequestTypeAAAA  CreateDNSDomainRecordRequestType = "AAAA"
	CreateDNSDomainRecordRequestTypeMX    CreateDNSDomainRecordRequestType = "MX"
	CreateDNSDomainRecordRequestTypeTXT   CreateDNSDomainRecordRequestType = "TXT"
	CreateDNSDomainRecordRequestTypeALIAS CreateDNSDomainRecordRequestType = "ALIAS"
	CreateDNSDomainRecordRequestTypeURL   CreateDNSDomainRecordRequestType = "URL"
)

type CreateDNSDomainRecordRequest struct {
	// DNS domain record content
	Content string `json:"content" validate:"required"`
	// DNS domain record name
	Name string `json:"name" validate:"required"`
	// DNS domain record priority
	Priority int64 `json:"priority,omitempty" validate:"omitempty,gte=0"`
	// DNS domain record TTL
	Ttl int64 `json:"ttl,omitempty" validate:"omitempty,gte=0"`
	// DNS domain record type
	Type CreateDNSDomainRecordRequestType `json:"type" validate:"required"`
}

// Create DNS domain record
func (c Client) CreateDNSDomainRecord(ctx context.Context, domainID UUID, req CreateDNSDomainRecordRequest) (*Operation, error) {
	path := fmt.Sprintf("/dns-domain/%v/record", domainID)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateDNSDomainRecord: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateDNSDomainRecord: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateDNSDomainRecord: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateDNSDomainRecord: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-dns-domain-record")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateDNSDomainRecord: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateDNSDomainRecord: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateDNSDomainRecord: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Delete DNS domain record
func (c Client) DeleteDNSDomainRecord(ctx context.Context, domainID UUID, recordID UUID) (*Operation, error) {
	path := fmt.Sprintf("/dns-domain/%v/record/%v", domainID, recordID)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteDNSDomainRecord: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteDNSDomainRecord: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteDNSDomainRecord: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-dns-domain-record")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteDNSDomainRecord: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteDNSDomainRecord: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteDNSDomainRecord: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Retrieve DNS domain record details
func (c Client) GetDNSDomainRecord(ctx context.Context, domainID UUID, recordID UUID) (*DNSDomainRecord, error) {
	path := fmt.Sprintf("/dns-domain/%v/record/%v", domainID, recordID)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDNSDomainRecord: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDNSDomainRecord: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDNSDomainRecord: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dns-domain-record")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDNSDomainRecord: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDNSDomainRecord: http response: %w", err)
	}

	bodyresp := new(DNSDomainRecord)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDNSDomainRecord: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type UpdateDNSDomainRecordRequest struct {
	// DNS domain record content
	Content string `json:"content,omitempty"`
	// DNS domain record name
	Name string `json:"name,omitempty"`
	// DNS domain record priority
	Priority int64 `json:"priority,omitempty" validate:"omitempty,gt=0"`
	// DNS domain record TTL
	Ttl int64 `json:"ttl,omitempty" validate:"omitempty,gt=0"`
}

// Update DNS domain record
func (c Client) UpdateDNSDomainRecord(ctx context.Context, domainID UUID, recordID UUID, req UpdateDNSDomainRecordRequest) (*Operation, error) {
	path := fmt.Sprintf("/dns-domain/%v/record/%v", domainID, recordID)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateDNSDomainRecord: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateDNSDomainRecord: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateDNSDomainRecord: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateDNSDomainRecord: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-dns-domain-record")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateDNSDomainRecord: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateDNSDomainRecord: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateDNSDomainRecord: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Delete DNS Domain
func (c Client) DeleteDNSDomain(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/dns-domain/%v", id)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteDNSDomain: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteDNSDomain: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteDNSDomain: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-dns-domain")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteDNSDomain: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteDNSDomain: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteDNSDomain: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Retrieve DNS domain details
func (c Client) GetDNSDomain(ctx context.Context, id UUID) (*DNSDomain, error) {
	path := fmt.Sprintf("/dns-domain/%v", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDNSDomain: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDNSDomain: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDNSDomain: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dns-domain")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDNSDomain: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDNSDomain: http response: %w", err)
	}

	bodyresp := new(DNSDomain)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDNSDomain: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type GetDNSDomainZoneFileResponse struct {
	ZoneFile string `json:"zone-file,omitempty"`
}

// Retrieve DNS domain zone file
func (c Client) GetDNSDomainZoneFile(ctx context.Context, id UUID) (*GetDNSDomainZoneFileResponse, error) {
	path := fmt.Sprintf("/dns-domain/%v/zone", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDNSDomainZoneFile: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDNSDomainZoneFile: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDNSDomainZoneFile: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dns-domain-zone-file")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDNSDomainZoneFile: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDNSDomainZoneFile: http response: %w", err)
	}

	bodyresp := new(GetDNSDomainZoneFileResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDNSDomainZoneFile: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ListElasticIPSResponse struct {
	ElasticIPS []ElasticIP `json:"elastic-ips,omitempty"`
}

// FindElasticIP attempts to find an ElasticIP by idOrIP.
func (l ListElasticIPSResponse) FindElasticIP(idOrIP string) (ElasticIP, error) {
	var result []ElasticIP
	for i, elem := range l.ElasticIPS {
		if string(elem.ID) == idOrIP || string(elem.IP) == idOrIP {
			result = append(result, l.ElasticIPS[i])
		}
	}
	if len(result) == 1 {
		return result[0], nil
	}

	if len(result) > 1 {
		return ElasticIP{}, fmt.Errorf("%q too many found in ListElasticIPSResponse: %w", idOrIP, ErrConflict)
	}

	return ElasticIP{}, fmt.Errorf("%q not found in ListElasticIPSResponse: %w", idOrIP, ErrNotFound)
}

// List Elastic IPs
func (c Client) ListElasticIPS(ctx context.Context) (*ListElasticIPSResponse, error) {
	path := "/elastic-ip"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListElasticIPS: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListElasticIPS: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListElasticIPS: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-elastic-ips")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListElasticIPS: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListElasticIPS: http response: %w", err)
	}

	bodyresp := new(ListElasticIPSResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListElasticIPS: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type CreateElasticIPRequestAddressfamily string

const (
	CreateElasticIPRequestAddressfamilyInet4 CreateElasticIPRequestAddressfamily = "inet4"
	CreateElasticIPRequestAddressfamilyInet6 CreateElasticIPRequestAddressfamily = "inet6"
)

type CreateElasticIPRequest struct {
	// Elastic IP address family (default: :inet4)
	Addressfamily CreateElasticIPRequestAddressfamily `json:"addressfamily,omitempty"`
	// Elastic IP description
	Description string `json:"description,omitempty" validate:"omitempty,lte=255"`
	// Elastic IP address healthcheck
	Healthcheck *ElasticIPHealthcheck `json:"healthcheck,omitempty"`
	Labels      Labels                `json:"labels,omitempty"`
}

// Create an Elastic IP
func (c Client) CreateElasticIP(ctx context.Context, req CreateElasticIPRequest) (*Operation, error) {
	path := "/elastic-ip"

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateElasticIP: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateElasticIP: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateElasticIP: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateElasticIP: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-elastic-ip")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateElasticIP: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateElasticIP: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateElasticIP: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Delete an Elastic IP
func (c Client) DeleteElasticIP(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/elastic-ip/%v", id)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteElasticIP: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteElasticIP: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteElasticIP: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-elastic-ip")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteElasticIP: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteElasticIP: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteElasticIP: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Retrieve Elastic IP details
func (c Client) GetElasticIP(ctx context.Context, id UUID) (*ElasticIP, error) {
	path := fmt.Sprintf("/elastic-ip/%v", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetElasticIP: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetElasticIP: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetElasticIP: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-elastic-ip")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetElasticIP: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetElasticIP: http response: %w", err)
	}

	bodyresp := new(ElasticIP)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetElasticIP: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type UpdateElasticIPRequest struct {
	// Elastic IP description
	Description string `json:"description,omitempty" validate:"omitempty,lte=255"`
	// Elastic IP address healthcheck
	Healthcheck *ElasticIPHealthcheck `json:"healthcheck,omitempty"`
	Labels      Labels                `json:"labels,omitempty"`
}

// Update an Elastic IP
func (c Client) UpdateElasticIP(ctx context.Context, id UUID, req UpdateElasticIPRequest) (*Operation, error) {
	path := fmt.Sprintf("/elastic-ip/%v", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateElasticIP: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateElasticIP: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateElasticIP: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateElasticIP: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-elastic-ip")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateElasticIP: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateElasticIP: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateElasticIP: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ResetElasticIPFieldField string

const (
	ResetElasticIPFieldFieldDescription ResetElasticIPFieldField = "description"
)

// Reset an Elastic IP field to its default value
func (c Client) ResetElasticIPField(ctx context.Context, id UUID, field ResetElasticIPFieldField) (*Operation, error) {
	path := fmt.Sprintf("/elastic-ip/%v/%v", id, field)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ResetElasticIPField: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ResetElasticIPField: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ResetElasticIPField: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reset-elastic-ip-field")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ResetElasticIPField: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ResetElasticIPField: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ResetElasticIPField: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type AttachInstanceToElasticIPRequest struct {
	// Target Instance
	Instance *InstanceTarget `json:"instance" validate:"required"`
}

// Attach a Compute instance to an Elastic IP
func (c Client) AttachInstanceToElasticIP(ctx context.Context, id UUID, req AttachInstanceToElasticIPRequest) (*Operation, error) {
	path := fmt.Sprintf("/elastic-ip/%v:attach", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("AttachInstanceToElasticIP: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("AttachInstanceToElasticIP: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("AttachInstanceToElasticIP: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("AttachInstanceToElasticIP: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "attach-instance-to-elastic-ip")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("AttachInstanceToElasticIP: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("AttachInstanceToElasticIP: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("AttachInstanceToElasticIP: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type DetachInstanceFromElasticIPRequest struct {
	// Target Instance
	Instance *InstanceTarget `json:"instance" validate:"required"`
}

// Detach a Compute instance from an Elastic IP
func (c Client) DetachInstanceFromElasticIP(ctx context.Context, id UUID, req DetachInstanceFromElasticIPRequest) (*Operation, error) {
	path := fmt.Sprintf("/elastic-ip/%v:detach", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("DetachInstanceFromElasticIP: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("DetachInstanceFromElasticIP: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DetachInstanceFromElasticIP: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DetachInstanceFromElasticIP: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "detach-instance-from-elastic-ip")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DetachInstanceFromElasticIP: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DetachInstanceFromElasticIP: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DetachInstanceFromElasticIP: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// [BETA] Returns environmental impact reports for an organization
func (c Client) GetEnvImpact(ctx context.Context, period string) (*EnvImpactReport, error) {
	path := fmt.Sprintf("/env-impact/%v", period)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetEnvImpact: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetEnvImpact: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetEnvImpact: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-env-impact")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetEnvImpact: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetEnvImpact: http response: %w", err)
	}

	bodyresp := new(EnvImpactReport)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetEnvImpact: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ListEventsOpt func(url.Values)

func ListEventsWithFrom(from time.Time) ListEventsOpt {
	return func(q url.Values) {
		q.Add("from", from.Format(time.RFC3339))
	}
}

func ListEventsWithTo(to time.Time) ListEventsOpt {
	return func(q url.Values) {
		q.Add("to", to.Format(time.RFC3339))
	}
}

// Retrieve Mutation Events for a given date range. Defaults to retrieving Events for the past 24 hours.
// Both a `from` and `to` arguments can be specified to filter Events over a specific period.
// Events will be the the most descriptive possible but not all fields are mandatory
func (c Client) ListEvents(ctx context.Context, opts ...ListEventsOpt) ([]Event, error) {
	path := "/event"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListEvents: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if len(opts) > 0 {
		q := request.URL.Query()
		for _, opt := range opts {
			opt(q)
		}
		request.URL.RawQuery = q.Encode()
	}

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListEvents: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListEvents: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-events")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListEvents: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListEvents: http response: %w", err)
	}

	bodyresp := []Event{}
	if err := prepareJSONResponse(response, &bodyresp); err != nil {
		return nil, fmt.Errorf("ListEvents: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Retrieve IAM Organization Policy
func (c Client) GetIAMOrganizationPolicy(ctx context.Context) (*IAMPolicy, error) {
	path := "/iam-organization-policy"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetIAMOrganizationPolicy: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetIAMOrganizationPolicy: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetIAMOrganizationPolicy: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-iam-organization-policy")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetIAMOrganizationPolicy: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetIAMOrganizationPolicy: http response: %w", err)
	}

	bodyresp := new(IAMPolicy)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetIAMOrganizationPolicy: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Update IAM Organization Policy
func (c Client) UpdateIAMOrganizationPolicy(ctx context.Context, req IAMPolicy) (*Operation, error) {
	path := "/iam-organization-policy"

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateIAMOrganizationPolicy: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateIAMOrganizationPolicy: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateIAMOrganizationPolicy: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateIAMOrganizationPolicy: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-iam-organization-policy")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateIAMOrganizationPolicy: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateIAMOrganizationPolicy: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateIAMOrganizationPolicy: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Reset IAM Organization Policy
func (c Client) ResetIAMOrganizationPolicy(ctx context.Context) (*Operation, error) {
	path := "/iam-organization-policy:reset"

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ResetIAMOrganizationPolicy: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ResetIAMOrganizationPolicy: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ResetIAMOrganizationPolicy: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reset-iam-organization-policy")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ResetIAMOrganizationPolicy: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ResetIAMOrganizationPolicy: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ResetIAMOrganizationPolicy: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ListIAMRolesResponse struct {
	IAMRoles []IAMRole `json:"iam-roles,omitempty"`
}

// FindIAMRole attempts to find an IAMRole by nameOrID.
func (l ListIAMRolesResponse) FindIAMRole(nameOrID string) (IAMRole, error) {
	var result []IAMRole
	for i, elem := range l.IAMRoles {
		if string(elem.Name) == nameOrID || string(elem.ID) == nameOrID {
			result = append(result, l.IAMRoles[i])
		}
	}
	if len(result) == 1 {
		return result[0], nil
	}

	if len(result) > 1 {
		return IAMRole{}, fmt.Errorf("%q too many found in ListIAMRolesResponse: %w", nameOrID, ErrConflict)
	}

	return IAMRole{}, fmt.Errorf("%q not found in ListIAMRolesResponse: %w", nameOrID, ErrNotFound)
}

// List IAM Roles
func (c Client) ListIAMRoles(ctx context.Context) (*ListIAMRolesResponse, error) {
	path := "/iam-role"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListIAMRoles: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListIAMRoles: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListIAMRoles: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-iam-roles")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListIAMRoles: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListIAMRoles: http response: %w", err)
	}

	bodyresp := new(ListIAMRolesResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListIAMRoles: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type CreateIAMRoleRequest struct {
	// Assume Role Policy
	AssumeRolePolicy *IAMAssumeRolePolicy `json:"assume-role-policy,omitempty"`
	// IAM Role description
	Description string `json:"description,omitempty" validate:"omitempty,gte=1,lte=255"`
	// Sets if the IAM Role Policy is editable or not (default: true). This setting cannot be changed after creation
	Editable *bool  `json:"editable,omitempty"`
	Labels   Labels `json:"labels,omitempty"`
	// Maximum TTL requester is allowed to ask for when assuming a role
	MaxSessionTtl int64 `json:"max-session-ttl,omitempty" validate:"omitempty,gt=0"`
	// IAM Role name
	Name string `json:"name" validate:"required,gte=1,lte=191"`
	// IAM Role permissions
	Permissions []string `json:"permissions,omitempty"`
	// Policy
	Policy *IAMPolicy `json:"policy,omitempty"`
}

// Create IAM Role
func (c Client) CreateIAMRole(ctx context.Context, req CreateIAMRoleRequest) (*Operation, error) {
	path := "/iam-role"

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateIAMRole: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateIAMRole: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateIAMRole: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateIAMRole: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-iam-role")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateIAMRole: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateIAMRole: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateIAMRole: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Delete IAM Role
func (c Client) DeleteIAMRole(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/iam-role/%v", id)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteIAMRole: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteIAMRole: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteIAMRole: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-iam-role")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteIAMRole: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteIAMRole: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteIAMRole: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Retrieve IAM Role
func (c Client) GetIAMRole(ctx context.Context, id UUID) (*IAMRole, error) {
	path := fmt.Sprintf("/iam-role/%v", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetIAMRole: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetIAMRole: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetIAMRole: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-iam-role")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetIAMRole: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetIAMRole: http response: %w", err)
	}

	bodyresp := new(IAMRole)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetIAMRole: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type UpdateIAMRoleRequest struct {
	// Assume Role Policy
	AssumeRolePolicy *IAMAssumeRolePolicy `json:"assume-role-policy,omitempty"`
	// IAM Role description
	Description string `json:"description,omitempty" validate:"omitempty,gte=1,lte=255"`
	Labels      Labels `json:"labels,omitempty"`
	// Maximum TTL requester is allowed to ask for when assuming a role
	MaxSessionTtl int64 `json:"max-session-ttl,omitempty" validate:"omitempty,gt=0"`
	// IAM Role permissions
	Permissions []string `json:"permissions,omitempty"`
}

// Update IAM Role
func (c Client) UpdateIAMRole(ctx context.Context, id UUID, req UpdateIAMRoleRequest) (*Operation, error) {
	path := fmt.Sprintf("/iam-role/%v", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateIAMRole: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateIAMRole: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateIAMRole: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateIAMRole: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-iam-role")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateIAMRole: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateIAMRole: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateIAMRole: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type AssumeIAMRoleResponse struct {
	ExpiresAT string `json:"expires-at,omitempty"`
	Key       string `json:"key,omitempty"`
	Name      string `json:"name,omitempty"`
	OrgID     string `json:"org-id,omitempty"`
	RoleID    string `json:"role-id,omitempty"`
	Secret    string `json:"secret,omitempty"`
}

type AssumeIAMRoleRequest struct {
	// TTL in seconds for the generated access key (cannot exceed the max TTL defined in the targeted assume role)
	Ttl int64 `json:"ttl" validate:"required,gt=0"`
}

// [BETA] Request generation of key/secret that allow caller to assume target role
func (c Client) AssumeIAMRole(ctx context.Context, id UUID, req AssumeIAMRoleRequest) (*AssumeIAMRoleResponse, error) {
	path := fmt.Sprintf("/iam-role/%v/assume", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("AssumeIAMRole: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("AssumeIAMRole: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("AssumeIAMRole: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("AssumeIAMRole: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "assume-iam-role")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("AssumeIAMRole: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("AssumeIAMRole: http response: %w", err)
	}

	bodyresp := new(AssumeIAMRoleResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("AssumeIAMRole: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Update IAM Role Policy
func (c Client) UpdateIAMRolePolicy(ctx context.Context, id UUID, req IAMPolicy) (*Operation, error) {
	path := fmt.Sprintf("/iam-role/%v:policy", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateIAMRolePolicy: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateIAMRolePolicy: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateIAMRolePolicy: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateIAMRolePolicy: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-iam-role-policy")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateIAMRolePolicy: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateIAMRolePolicy: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateIAMRolePolicy: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Private Network
type ListInstancesResponseInstancesPrivateNetworks struct {
	// Private Network ID
	ID UUID `json:"id,omitempty"`
	// Private Network MAC address
	MACAddress string `json:"mac-address,omitempty"`
}

// Instance
type ListInstancesResponseInstances struct {
	// Instance creation date
	CreatedAT time.Time `json:"created-at,omitempty"`
	// Instance ID
	ID UUID `json:"id,omitempty"`
	// Compute instance type
	InstanceType *InstanceType `json:"instance-type,omitempty"`
	// Instance IPv6 address
	Ipv6Address string `json:"ipv6-address,omitempty"`
	Labels      Labels `json:"labels,omitempty"`
	// Instance MAC address
	MACAddress string `json:"mac-address,omitempty"`
	// Resource manager
	Manager *Manager `json:"manager,omitempty"`
	// Instance name
	Name string `json:"name,omitempty" validate:"omitempty,gte=1,lte=255"`
	// Instance Private Networks
	PrivateNetworks []ListInstancesResponseInstancesPrivateNetworks `json:"private-networks,omitempty"`
	// Instance public IPv4 address
	PublicIP           net.IP             `json:"public-ip,omitempty"`
	PublicIPAssignment PublicIPAssignment `json:"public-ip-assignment,omitempty"`
	// Instance Security Groups
	SecurityGroups []SecurityGroup `json:"security-groups,omitempty"`
	// SSH key
	SSHKey *SSHKey `json:"ssh-key,omitempty"`
	// Instance SSH Keys
	SSHKeys []SSHKey      `json:"ssh-keys,omitempty"`
	State   InstanceState `json:"state,omitempty"`
	// Instance template
	Template *Template `json:"template,omitempty"`
}

type ListInstancesResponse struct {
	Instances []ListInstancesResponseInstances `json:"instances,omitempty"`
}

// FindListInstancesResponseInstances attempts to find an ListInstancesResponseInstances by nameOrID.
func (l ListInstancesResponse) FindListInstancesResponseInstances(nameOrID string) (ListInstancesResponseInstances, error) {
	var result []ListInstancesResponseInstances
	for i, elem := range l.Instances {
		if string(elem.Name) == nameOrID || string(elem.ID) == nameOrID {
			result = append(result, l.Instances[i])
		}
	}
	if len(result) == 1 {
		return result[0], nil
	}

	if len(result) > 1 {
		return ListInstancesResponseInstances{}, fmt.Errorf("%q too many found in ListInstancesResponse: %w", nameOrID, ErrConflict)
	}

	return ListInstancesResponseInstances{}, fmt.Errorf("%q not found in ListInstancesResponse: %w", nameOrID, ErrNotFound)
}

type ListInstancesManagerType string

const (
	ListInstancesManagerTypeInstancePool ListInstancesManagerType = "instance-pool"
)

type ListInstancesOpt func(url.Values)

func ListInstancesWithManagerID(managerID UUID) ListInstancesOpt {
	return func(q url.Values) {
		q.Add("manager-id", fmt.Sprint(managerID))
	}
}

func ListInstancesWithManagerType(managerType ListInstancesManagerType) ListInstancesOpt {
	return func(q url.Values) {
		q.Add("manager-type", fmt.Sprint(managerType))
	}
}

func ListInstancesWithIPAddress(ipAddress string) ListInstancesOpt {
	return func(q url.Values) {
		q.Add("ip-address", fmt.Sprint(ipAddress))
	}
}

func ListInstancesWithLabels(labels string) ListInstancesOpt {
	return func(q url.Values) {
		q.Add("labels", fmt.Sprint(labels))
	}
}

// List Compute instances
func (c Client) ListInstances(ctx context.Context, opts ...ListInstancesOpt) (*ListInstancesResponse, error) {
	path := "/instance"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListInstances: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if len(opts) > 0 {
		q := request.URL.Query()
		for _, opt := range opts {
			opt(q)
		}
		request.URL.RawQuery = q.Encode()
	}

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListInstances: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListInstances: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-instances")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListInstances: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListInstances: http response: %w", err)
	}

	bodyresp := new(ListInstancesResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListInstances: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type CreateInstanceRequest struct {
	// Instance Anti-affinity Groups
	AntiAffinityGroups []AntiAffinityGroup `json:"anti-affinity-groups,omitempty"`
	// Enable application-consistent snapshot for the instance
	ApplicationConsistentSnapshotEnabled *bool `json:"application-consistent-snapshot-enabled,omitempty"`
	// Start Instance on creation (default: true)
	AutoStart *bool `json:"auto-start,omitempty"`
	// Deploy target reference
	DeployTarget *DeployTarget `json:"deploy-target,omitempty"`
	// Instance disk size in GiB
	DiskSize int64 `json:"disk-size" validate:"required,gte=10,lte=51200"`
	// Instance type reference
	InstanceType *InstanceType `json:"instance-type" validate:"required"`
	// Enable IPv6. DEPRECATED: use `public-ip-assignments`.
	Ipv6Enabled *bool  `json:"ipv6-enabled,omitempty"`
	Labels      Labels `json:"labels,omitempty"`
	// Instance name
	Name               string             `json:"name,omitempty" validate:"omitempty,gte=1,lte=255"`
	PublicIPAssignment PublicIPAssignment `json:"public-ip-assignment,omitempty"`
	// Enable secure boot
	SecurebootEnabled *bool `json:"secureboot-enabled,omitempty"`
	// Instance Security Groups
	SecurityGroups []SecurityGroup `json:"security-groups,omitempty"`
	// SSH key reference
	SSHKey *SSHKey `json:"ssh-key,omitempty"`
	// Instance SSH Keys
	SSHKeys []SSHKey `json:"ssh-keys,omitempty"`
	// Template reference
	Template *Template `json:"template" validate:"required"`
	// Enable Trusted Platform Module (TPM)
	TpmEnabled *bool `json:"tpm-enabled,omitempty"`
	// Instance Cloud-init user-data (base64 encoded)
	UserData string `json:"user-data,omitempty" validate:"omitempty,gte=1,lte=32768"`
}

// Create a Compute instance
func (c Client) CreateInstance(ctx context.Context, req CreateInstanceRequest) (*Operation, error) {
	path := "/instance"

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateInstance: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateInstance: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateInstance: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateInstance: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-instance")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateInstance: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateInstance: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateInstance: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ListInstancePoolsResponse struct {
	InstancePools []InstancePool `json:"instance-pools,omitempty"`
}

// FindInstancePool attempts to find an InstancePool by nameOrID.
func (l ListInstancePoolsResponse) FindInstancePool(nameOrID string) (InstancePool, error) {
	var result []InstancePool
	for i, elem := range l.InstancePools {
		if string(elem.Name) == nameOrID || string(elem.ID) == nameOrID {
			result = append(result, l.InstancePools[i])
		}
	}
	if len(result) == 1 {
		return result[0], nil
	}

	if len(result) > 1 {
		return InstancePool{}, fmt.Errorf("%q too many found in ListInstancePoolsResponse: %w", nameOrID, ErrConflict)
	}

	return InstancePool{}, fmt.Errorf("%q not found in ListInstancePoolsResponse: %w", nameOrID, ErrNotFound)
}

// List Instance Pools
func (c Client) ListInstancePools(ctx context.Context) (*ListInstancePoolsResponse, error) {
	path := "/instance-pool"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListInstancePools: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListInstancePools: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListInstancePools: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-instance-pools")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListInstancePools: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListInstancePools: http response: %w", err)
	}

	bodyresp := new(ListInstancePoolsResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListInstancePools: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type CreateInstancePoolRequestPublicIPAssignment string

const (
	CreateInstancePoolRequestPublicIPAssignmentInet4 CreateInstancePoolRequestPublicIPAssignment = "inet4"
	CreateInstancePoolRequestPublicIPAssignmentDual  CreateInstancePoolRequestPublicIPAssignment = "dual"
	CreateInstancePoolRequestPublicIPAssignmentNone  CreateInstancePoolRequestPublicIPAssignment = "none"
)

type CreateInstancePoolRequest struct {
	// Instance Pool Anti-affinity Groups
	AntiAffinityGroups []AntiAffinityGroup `json:"anti-affinity-groups,omitempty"`
	// Enable application consistent snapshots
	ApplicationConsistentSnapshotEnabled *bool `json:"application-consistent-snapshot-enabled,omitempty"`
	// Deploy target reference
	DeployTarget *DeployTarget `json:"deploy-target,omitempty"`
	// Instance Pool description
	Description string `json:"description,omitempty" validate:"omitempty,lte=255"`
	// Instances disk size in GiB
	DiskSize int64 `json:"disk-size" validate:"required,gte=10,lte=51200"`
	// Instances Elastic IPs
	ElasticIPS []ElasticIP `json:"elastic-ips,omitempty"`
	// Prefix to apply to Instances names (default: pool)
	InstancePrefix string `json:"instance-prefix,omitempty" validate:"omitempty,gte=1,lte=30"`
	// Instance type reference
	InstanceType *InstanceType `json:"instance-type" validate:"required"`
	// Enable IPv6. DEPRECATED: use `public-ip-assignments`.
	Ipv6Enabled *bool  `json:"ipv6-enabled,omitempty"`
	Labels      Labels `json:"labels,omitempty"`
	// Minimum number of running Instances
	MinAvailable int64 `json:"min-available,omitempty" validate:"omitempty,gte=0"`
	// Instance Pool name
	Name string `json:"name" validate:"required,gte=1,lte=255"`
	// Instance Pool Private Networks
	PrivateNetworks []PrivateNetwork `json:"private-networks,omitempty"`
	// Determines public IP assignment of the Instances. Type `none` is final and can't be changed later on.
	PublicIPAssignment CreateInstancePoolRequestPublicIPAssignment `json:"public-ip-assignment,omitempty"`
	// Instance Pool Security Groups
	SecurityGroups []SecurityGroup `json:"security-groups,omitempty"`
	// Number of Instances
	Size int64 `json:"size" validate:"required,gt=0"`
	// SSH key reference
	SSHKey *SSHKey `json:"ssh-key,omitempty"`
	// Instances SSH Keys
	SSHKeys []SSHKey `json:"ssh-keys,omitempty"`
	// Template reference
	Template *Template `json:"template" validate:"required"`
	// Instances Cloud-init user-data
	UserData string `json:"user-data,omitempty" validate:"omitempty,gte=1,lte=32768"`
}

// Create an Instance Pool
func (c Client) CreateInstancePool(ctx context.Context, req CreateInstancePoolRequest) (*Operation, error) {
	path := "/instance-pool"

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateInstancePool: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateInstancePool: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateInstancePool: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateInstancePool: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-instance-pool")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateInstancePool: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateInstancePool: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateInstancePool: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Delete an Instance Pool
func (c Client) DeleteInstancePool(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/instance-pool/%v", id)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteInstancePool: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteInstancePool: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteInstancePool: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-instance-pool")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteInstancePool: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteInstancePool: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteInstancePool: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Retrieve Instance Pool details
func (c Client) GetInstancePool(ctx context.Context, id UUID) (*InstancePool, error) {
	path := fmt.Sprintf("/instance-pool/%v", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetInstancePool: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetInstancePool: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetInstancePool: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-instance-pool")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetInstancePool: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetInstancePool: http response: %w", err)
	}

	bodyresp := new(InstancePool)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetInstancePool: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type UpdateInstancePoolRequestPublicIPAssignment string

const (
	UpdateInstancePoolRequestPublicIPAssignmentInet4 UpdateInstancePoolRequestPublicIPAssignment = "inet4"
	UpdateInstancePoolRequestPublicIPAssignmentDual  UpdateInstancePoolRequestPublicIPAssignment = "dual"
)

type UpdateInstancePoolRequest struct {
	// Instance Pool Anti-affinity Groups
	AntiAffinityGroups []AntiAffinityGroup `json:"anti-affinity-groups"`
	// Enable application consistent snapshots
	ApplicationConsistentSnapshotEnabled *bool `json:"application-consistent-snapshot-enabled,omitempty"`
	// Deploy target reference
	DeployTarget *DeployTarget `json:"deploy-target"`
	// Instance Pool description
	Description string `json:"description,omitempty" validate:"omitempty,lte=255"`
	// Instances disk size in GiB
	DiskSize int64 `json:"disk-size,omitempty" validate:"omitempty,gte=10,lte=51200"`
	// Instances Elastic IPs
	ElasticIPS []ElasticIP `json:"elastic-ips"`
	// Prefix to apply to Instances names (default: pool)
	InstancePrefix *string `json:"instance-prefix,omitempty"`
	// Instance type reference
	InstanceType *InstanceType `json:"instance-type,omitempty"`
	// Enable IPv6. DEPRECATED: use `public-ip-assignments`.
	Ipv6Enabled *bool  `json:"ipv6-enabled,omitempty"`
	Labels      Labels `json:"labels,omitempty"`
	// Minimum number of running Instances
	MinAvailable *int64 `json:"min-available,omitempty" validate:"omitempty,gte=0"`
	// Instance Pool name
	Name string `json:"name,omitempty" validate:"omitempty,gte=1,lte=255"`
	// Instance Pool Private Networks
	PrivateNetworks []PrivateNetwork `json:"private-networks"`
	// Determines public IP assignment of the Instances.
	PublicIPAssignment UpdateInstancePoolRequestPublicIPAssignment `json:"public-ip-assignment,omitempty"`
	// Instance Pool Security Groups
	SecurityGroups []SecurityGroup `json:"security-groups"`
	// SSH key reference
	SSHKey *SSHKey `json:"ssh-key"`
	// Instances SSH keys
	SSHKeys []SSHKey `json:"ssh-keys"`
	// Template reference
	Template *Template `json:"template,omitempty"`
	// Instances Cloud-init user-data
	UserData *string `json:"user-data,omitempty" validate:"omitempty,gte=1"`
}

// Update an Instance Pool
func (c Client) UpdateInstancePool(ctx context.Context, id UUID, req UpdateInstancePoolRequest) (*Operation, error) {
	path := fmt.Sprintf("/instance-pool/%v", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateInstancePool: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateInstancePool: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateInstancePool: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateInstancePool: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-instance-pool")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateInstancePool: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateInstancePool: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateInstancePool: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ResetInstancePoolFieldField string

const (
	ResetInstancePoolFieldFieldAntiAffinityGroups ResetInstancePoolFieldField = "anti-affinity-groups"
	ResetInstancePoolFieldFieldDescription        ResetInstancePoolFieldField = "description"
	ResetInstancePoolFieldFieldLabels             ResetInstancePoolFieldField = "labels"
	ResetInstancePoolFieldFieldSecurityGroups     ResetInstancePoolFieldField = "security-groups"
	ResetInstancePoolFieldFieldElasticIPS         ResetInstancePoolFieldField = "elastic-ips"
	ResetInstancePoolFieldFieldPrivateNetworks    ResetInstancePoolFieldField = "private-networks"
	ResetInstancePoolFieldFieldSSHKey             ResetInstancePoolFieldField = "ssh-key"
	ResetInstancePoolFieldFieldUserData           ResetInstancePoolFieldField = "user-data"
	ResetInstancePoolFieldFieldDeployTarget       ResetInstancePoolFieldField = "deploy-target"
	ResetInstancePoolFieldFieldIpv6Enabled        ResetInstancePoolFieldField = "ipv6-enabled"
)

// Reset an Instance Pool field to its default value
func (c Client) ResetInstancePoolField(ctx context.Context, id UUID, field ResetInstancePoolFieldField) (*Operation, error) {
	path := fmt.Sprintf("/instance-pool/%v/%v", id, field)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ResetInstancePoolField: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ResetInstancePoolField: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ResetInstancePoolField: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reset-instance-pool-field")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ResetInstancePoolField: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ResetInstancePoolField: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ResetInstancePoolField: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type EvictInstancePoolMembersRequest struct {
	Instances []UUID `json:"instances,omitempty"`
}

// This operation evicts the specified Compute instances member from the Instance Pool, shrinking it to `&lt;current pool size&gt; - &lt;# evicted members&gt;`.
func (c Client) EvictInstancePoolMembers(ctx context.Context, id UUID, req EvictInstancePoolMembersRequest) (*Operation, error) {
	path := fmt.Sprintf("/instance-pool/%v:evict", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("EvictInstancePoolMembers: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("EvictInstancePoolMembers: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("EvictInstancePoolMembers: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("EvictInstancePoolMembers: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "evict-instance-pool-members")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("EvictInstancePoolMembers: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("EvictInstancePoolMembers: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("EvictInstancePoolMembers: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ScaleInstancePoolRequest struct {
	// Number of managed Instances
	Size int64 `json:"size" validate:"required,gte=0"`
}

// Scale an Instance Pool
func (c Client) ScaleInstancePool(ctx context.Context, id UUID, req ScaleInstancePoolRequest) (*Operation, error) {
	path := fmt.Sprintf("/instance-pool/%v:scale", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("ScaleInstancePool: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("ScaleInstancePool: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ScaleInstancePool: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ScaleInstancePool: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "scale-instance-pool")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ScaleInstancePool: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ScaleInstancePool: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ScaleInstancePool: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ListInstanceTypesResponse struct {
	InstanceTypes []InstanceType `json:"instance-types,omitempty"`
}

// FindInstanceType attempts to find an InstanceType by id.
func (l ListInstanceTypesResponse) FindInstanceType(id string) (InstanceType, error) {
	var result []InstanceType
	for i, elem := range l.InstanceTypes {
		if string(elem.ID) == id {
			result = append(result, l.InstanceTypes[i])
		}
	}
	if len(result) == 1 {
		return result[0], nil
	}

	if len(result) > 1 {
		return InstanceType{}, fmt.Errorf("%q too many found in ListInstanceTypesResponse: %w", id, ErrConflict)
	}

	return InstanceType{}, fmt.Errorf("%q not found in ListInstanceTypesResponse: %w", id, ErrNotFound)
}

// List Compute instance Types
func (c Client) ListInstanceTypes(ctx context.Context) (*ListInstanceTypesResponse, error) {
	path := "/instance-type"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListInstanceTypes: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListInstanceTypes: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListInstanceTypes: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-instance-types")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListInstanceTypes: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListInstanceTypes: http response: %w", err)
	}

	bodyresp := new(ListInstanceTypesResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListInstanceTypes: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Retrieve Instance Type details
func (c Client) GetInstanceType(ctx context.Context, id UUID) (*InstanceType, error) {
	path := fmt.Sprintf("/instance-type/%v", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetInstanceType: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetInstanceType: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetInstanceType: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-instance-type")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetInstanceType: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetInstanceType: http response: %w", err)
	}

	bodyresp := new(InstanceType)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetInstanceType: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Delete a Compute instance
func (c Client) DeleteInstance(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/instance/%v", id)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteInstance: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteInstance: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteInstance: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-instance")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteInstance: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteInstance: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteInstance: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Retrieve Compute instance details
func (c Client) GetInstance(ctx context.Context, id UUID) (*Instance, error) {
	path := fmt.Sprintf("/instance/%v", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetInstance: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetInstance: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetInstance: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-instance")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetInstance: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetInstance: http response: %w", err)
	}

	bodyresp := new(Instance)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetInstance: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type UpdateInstanceRequest struct {
	// Enable/Disable Application Consistent Snapshot for Instance
	ApplicationConsistentSnapshotEnabled *bool  `json:"application-consistent-snapshot-enabled,omitempty"`
	Labels                               Labels `json:"labels"`
	// Instance name
	Name               string             `json:"name,omitempty" validate:"omitempty,gte=1,lte=255"`
	PublicIPAssignment PublicIPAssignment `json:"public-ip-assignment,omitempty"`
	// Instance Cloud-init user-data (base64 encoded)
	UserData string `json:"user-data,omitempty" validate:"omitempty,gte=1,lte=32768"`
}

// Update a Compute instance
func (c Client) UpdateInstance(ctx context.Context, id UUID, req UpdateInstanceRequest) (*Operation, error) {
	path := fmt.Sprintf("/instance/%v", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateInstance: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateInstance: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateInstance: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateInstance: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-instance")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateInstance: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateInstance: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateInstance: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ResetInstanceFieldField string

const (
	ResetInstanceFieldFieldLabels ResetInstanceFieldField = "labels"
)

// Reset Instance field
func (c Client) ResetInstanceField(ctx context.Context, id UUID, field ResetInstanceFieldField) (*Operation, error) {
	path := fmt.Sprintf("/instance/%v/%v", id, field)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ResetInstanceField: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ResetInstanceField: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ResetInstanceField: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reset-instance-field")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ResetInstanceField: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ResetInstanceField: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ResetInstanceField: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Set instance destruction protection
func (c Client) AddInstanceProtection(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/instance/%v:add-protection", id)

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("AddInstanceProtection: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("AddInstanceProtection: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("AddInstanceProtection: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "add-instance-protection")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("AddInstanceProtection: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("AddInstanceProtection: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("AddInstanceProtection: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Create a Snapshot of a Compute instance
func (c Client) CreateSnapshot(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/instance/%v:create-snapshot", id)

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("CreateSnapshot: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateSnapshot: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateSnapshot: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-snapshot")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateSnapshot: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateSnapshot: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateSnapshot: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Enable tpm for the instance.
func (c Client) EnableTpm(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/instance/%v:enable-tpm", id)

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("EnableTpm: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("EnableTpm: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("EnableTpm: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "enable-tpm")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("EnableTpm: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("EnableTpm: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("EnableTpm: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Reveal the password used during instance creation or the latest password reset.
// This is only available for VMs created against templates having the `password-enabled`
// property set to `true`.
// creation or resets.
// creation or resets.
func (c Client) RevealInstancePassword(ctx context.Context, id UUID) (*InstancePassword, error) {
	path := fmt.Sprintf("/instance/%v:password", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("RevealInstancePassword: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("RevealInstancePassword: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("RevealInstancePassword: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reveal-instance-password")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("RevealInstancePassword: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("RevealInstancePassword: http response: %w", err)
	}

	bodyresp := new(InstancePassword)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("RevealInstancePassword: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Reboot a Compute instance
func (c Client) RebootInstance(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/instance/%v:reboot", id)

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("RebootInstance: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("RebootInstance: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("RebootInstance: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reboot-instance")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("RebootInstance: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("RebootInstance: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("RebootInstance: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Remove instance destruction protection
func (c Client) RemoveInstanceProtection(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/instance/%v:remove-protection", id)

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("RemoveInstanceProtection: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("RemoveInstanceProtection: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("RemoveInstanceProtection: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "remove-instance-protection")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("RemoveInstanceProtection: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("RemoveInstanceProtection: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("RemoveInstanceProtection: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ResetInstanceRequest struct {
	// Instance disk size in GiB
	DiskSize int64 `json:"disk-size,omitempty" validate:"omitempty,gte=10,lte=51200"`
	// Template reference
	Template *Template `json:"template,omitempty"`
}

// This operation re-installs a Compute instance to a base template. If target template is provided it will be used to recreated instance from. Warning: the operation wipes all data stored on the disk.
func (c Client) ResetInstance(ctx context.Context, id UUID, req ResetInstanceRequest) (*Operation, error) {
	path := fmt.Sprintf("/instance/%v:reset", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("ResetInstance: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("ResetInstance: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ResetInstance: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ResetInstance: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reset-instance")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ResetInstance: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ResetInstance: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ResetInstance: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Reset a compute instance password
func (c Client) ResetInstancePassword(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/instance/%v:reset-password", id)

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ResetInstancePassword: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ResetInstancePassword: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ResetInstancePassword: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reset-instance-password")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ResetInstancePassword: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ResetInstancePassword: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ResetInstancePassword: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ResizeInstanceDiskRequest struct {
	// Instance disk size in GiB
	DiskSize int64 `json:"disk-size" validate:"required,gte=10,lte=51200"`
}

// This operation resizes a Compute instance's disk volume. Note: the disk can only grow, cannot be shrunk.
func (c Client) ResizeInstanceDisk(ctx context.Context, id UUID, req ResizeInstanceDiskRequest) (*Operation, error) {
	path := fmt.Sprintf("/instance/%v:resize-disk", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("ResizeInstanceDisk: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("ResizeInstanceDisk: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ResizeInstanceDisk: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ResizeInstanceDisk: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "resize-instance-disk")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ResizeInstanceDisk: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ResizeInstanceDisk: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ResizeInstanceDisk: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ScaleInstanceRequest struct {
	// Instance type reference
	InstanceType *InstanceType `json:"instance-type" validate:"required"`
}

// This operation changes the Compute instance's type. Note: the new Instance Type must be within the same family (e.g. a standard instance cannot be scaled to gpu2 or storage).
func (c Client) ScaleInstance(ctx context.Context, id UUID, req ScaleInstanceRequest) (*Operation, error) {
	path := fmt.Sprintf("/instance/%v:scale", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("ScaleInstance: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("ScaleInstance: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ScaleInstance: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ScaleInstance: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "scale-instance")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ScaleInstance: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ScaleInstance: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ScaleInstance: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type StartInstanceRequestRescueProfile string

const (
	StartInstanceRequestRescueProfileNetbootEfi StartInstanceRequestRescueProfile = "netboot-efi"
	StartInstanceRequestRescueProfileNetboot    StartInstanceRequestRescueProfile = "netboot"
)

type StartInstanceRequest struct {
	// Boot in Rescue Mode, using named profile (supported: netboot, netboot-efi)
	RescueProfile StartInstanceRequestRescueProfile `json:"rescue-profile,omitempty"`
}

// This operation starts a virtual machine, potentially using a rescue profile if specified
func (c Client) StartInstance(ctx context.Context, id UUID, req StartInstanceRequest) (*Operation, error) {
	path := fmt.Sprintf("/instance/%v:start", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("StartInstance: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("StartInstance: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("StartInstance: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("StartInstance: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "start-instance")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("StartInstance: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("StartInstance: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("StartInstance: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Stop a Compute instance
func (c Client) StopInstance(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/instance/%v:stop", id)

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("StopInstance: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("StopInstance: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("StopInstance: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "stop-instance")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("StopInstance: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("StopInstance: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("StopInstance: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type RevertInstanceToSnapshotRequest struct {
	// Snapshot ID
	ID UUID `json:"id" validate:"required"`
}

// This operation reverts the snapshot to the Compute instance volume, restoring stored data as it was at the time of the snapshot.
// The Compute instance must be previously stopped.
func (c Client) RevertInstanceToSnapshot(ctx context.Context, instanceID UUID, req RevertInstanceToSnapshotRequest) (*Operation, error) {
	path := fmt.Sprintf("/instance/%v:revert-snapshot", instanceID)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("RevertInstanceToSnapshot: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("RevertInstanceToSnapshot: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("RevertInstanceToSnapshot: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("RevertInstanceToSnapshot: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "revert-instance-to-snapshot")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("RevertInstanceToSnapshot: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("RevertInstanceToSnapshot: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("RevertInstanceToSnapshot: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// FindListKmsKeysResponseEntry attempts to find an ListKmsKeysResponseEntry by nameOrID.
func (l ListKmsKeysResponse) FindListKmsKeysResponseEntry(nameOrID string) (ListKmsKeysResponseEntry, error) {
	var result []ListKmsKeysResponseEntry
	for i, elem := range l.KmsKeys {
		if string(elem.Name) == nameOrID || string(elem.ID) == nameOrID {
			result = append(result, l.KmsKeys[i])
		}
	}
	if len(result) == 1 {
		return result[0], nil
	}

	if len(result) > 1 {
		return ListKmsKeysResponseEntry{}, fmt.Errorf("%q too many found in ListKmsKeysResponse: %w", nameOrID, ErrConflict)
	}

	return ListKmsKeysResponseEntry{}, fmt.Errorf("%q not found in ListKmsKeysResponse: %w", nameOrID, ErrNotFound)
}

// Lists all KMS Keys in your organization in a given zone.
func (c Client) ListKmsKeys(ctx context.Context) (*ListKmsKeysResponse, error) {
	path := "/kms-key"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListKmsKeys: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListKmsKeys: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListKmsKeys: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-kms-keys")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListKmsKeys: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListKmsKeys: http response: %w", err)
	}

	bodyresp := new(ListKmsKeysResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListKmsKeys: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Create a customer-managed unique KMS Key in your organization. A KMS Key is a logical representation of a cryptographic key material. It also includes metadata such as a UUID, a name and its state.
func (c Client) CreateKmsKey(ctx context.Context, req CreateKmsKeyRequest) (*CreateKmsKeyResponse, error) {
	path := "/kms-key"

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateKmsKey: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateKmsKey: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateKmsKey: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateKmsKey: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-kms-key")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateKmsKey: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateKmsKey: http response: %w", err)
	}

	bodyresp := new(CreateKmsKeyResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateKmsKey: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Retrieve KMS Key details.
func (c Client) GetKmsKey(ctx context.Context, id UUID) (*GetKmsKeyResponse, error) {
	path := fmt.Sprintf("/kms-key/%v", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetKmsKey: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetKmsKey: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetKmsKey: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-kms-key")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetKmsKey: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetKmsKey: http response: %w", err)
	}

	bodyresp := new(GetKmsKeyResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetKmsKey: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Cancels the scheduled deletion of a KMS Key.
func (c Client) CancelKmsKeyDeletion(ctx context.Context, id UUID) (*SuccessResponse, error) {
	path := fmt.Sprintf("/kms-key/%v/cancel-deletion", id)

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("CancelKmsKeyDeletion: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CancelKmsKeyDeletion: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CancelKmsKeyDeletion: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "cancel-kms-key-deletion")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CancelKmsKeyDeletion: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CancelKmsKeyDeletion: http response: %w", err)
	}

	bodyresp := new(SuccessResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CancelKmsKeyDeletion: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Decrypts a ciphertext.
func (c Client) Decrypt(ctx context.Context, id UUID, req DecryptRequest) (*DecryptResponse, error) {
	path := fmt.Sprintf("/kms-key/%v/decrypt", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("Decrypt: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("Decrypt: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("Decrypt: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("Decrypt: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "decrypt")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("Decrypt: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("Decrypt: http response: %w", err)
	}

	bodyresp := new(DecryptResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("Decrypt: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Disables a KMS Key by setting its state to "disabled". This prevents the use of the KMS key for cryptographic and key lifecycle operations.
func (c Client) DisableKmsKey(ctx context.Context, id UUID) (*SuccessResponse, error) {
	path := fmt.Sprintf("/kms-key/%v/disable", id)

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DisableKmsKey: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DisableKmsKey: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DisableKmsKey: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "disable-kms-key")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DisableKmsKey: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DisableKmsKey: http response: %w", err)
	}

	bodyresp := new(SuccessResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DisableKmsKey: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Disable the periodic rotation of a KMS Key.
func (c Client) DisableKmsKeyRotation(ctx context.Context, id UUID) (*DisableKmsKeyRotationResponse, error) {
	path := fmt.Sprintf("/kms-key/%v/disable-key-rotation", id)

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DisableKmsKeyRotation: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DisableKmsKeyRotation: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DisableKmsKeyRotation: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "disable-kms-key-rotation")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DisableKmsKeyRotation: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DisableKmsKeyRotation: http response: %w", err)
	}

	bodyresp := new(DisableKmsKeyRotationResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DisableKmsKeyRotation: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Enables a KMS Key by setting its state to "enabled". It restores the ability to fully use the KMS key for cryptographic operations and key lifecycle operations.
func (c Client) EnableKmsKey(ctx context.Context, id UUID) (*SuccessResponse, error) {
	path := fmt.Sprintf("/kms-key/%v/enable", id)

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("EnableKmsKey: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("EnableKmsKey: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("EnableKmsKey: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "enable-kms-key")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("EnableKmsKey: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("EnableKmsKey: http response: %w", err)
	}

	bodyresp := new(SuccessResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("EnableKmsKey: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Enable the periodic rotation of a KMS Key.
func (c Client) EnableKmsKeyRotation(ctx context.Context, id UUID, req EnableKmsKeyRotationRequest) (*EnableKmsKeyRotationResponse, error) {
	path := fmt.Sprintf("/kms-key/%v/enable-key-rotation", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("EnableKmsKeyRotation: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("EnableKmsKeyRotation: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("EnableKmsKeyRotation: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("EnableKmsKeyRotation: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "enable-kms-key-rotation")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("EnableKmsKeyRotation: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("EnableKmsKeyRotation: http response: %w", err)
	}

	bodyresp := new(EnableKmsKeyRotationResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("EnableKmsKeyRotation: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Encrypts a plaintext.
func (c Client) Encrypt(ctx context.Context, id UUID, req EncryptRequest) (*EncryptResponse, error) {
	path := fmt.Sprintf("/kms-key/%v/encrypt", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("Encrypt: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("Encrypt: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("Encrypt: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("Encrypt: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "encrypt")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("Encrypt: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("Encrypt: http response: %w", err)
	}

	bodyresp := new(EncryptResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("Encrypt: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Generate a Data Encryption Key from a given KMS Key.
func (c Client) GenerateDataKey(ctx context.Context, id UUID, req GenerateDataKeyRequest) (*GenerateDataKeyResponse, error) {
	path := fmt.Sprintf("/kms-key/%v/generate-data-key", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("GenerateDataKey: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("GenerateDataKey: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GenerateDataKey: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GenerateDataKey: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "generate-data-key")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GenerateDataKey: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GenerateDataKey: http response: %w", err)
	}

	bodyresp := new(GenerateDataKeyResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GenerateDataKey: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// List all the key material versions of a KMS Key.
func (c Client) ListKmsKeyRotations(ctx context.Context, id UUID) (*ListKmsKeyRotationsResponse, error) {
	path := fmt.Sprintf("/kms-key/%v/list-key-rotations", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListKmsKeyRotations: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListKmsKeyRotations: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListKmsKeyRotations: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-kms-key-rotations")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListKmsKeyRotations: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListKmsKeyRotations: http response: %w", err)
	}

	bodyresp := new(ListKmsKeyRotationsResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListKmsKeyRotations: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Decrypts an existing ciphertext using its original key material and re-encrypts the underlying plaintext using a specified KMS key or the latest key material of the same KMS Key.
func (c Client) ReEncrypt(ctx context.Context, id UUID, req ReEncryptRequest) (*ReEncryptResponse, error) {
	path := fmt.Sprintf("/kms-key/%v/re-encrypt", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("ReEncrypt: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("ReEncrypt: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ReEncrypt: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ReEncrypt: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "re-encrypt")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ReEncrypt: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ReEncrypt: http response: %w", err)
	}

	bodyresp := new(ReEncryptResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ReEncrypt: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Replicate a KMS key to a target zone.
func (c Client) ReplicateKmsKey(ctx context.Context, id UUID, req ReplicateKmsKeyRequest) (*SuccessResponse, error) {
	path := fmt.Sprintf("/kms-key/%v/replicate", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("ReplicateKmsKey: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("ReplicateKmsKey: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ReplicateKmsKey: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ReplicateKmsKey: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "replicate-kms-key")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ReplicateKmsKey: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ReplicateKmsKey: http response: %w", err)
	}

	bodyresp := new(SuccessResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ReplicateKmsKey: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Performs an immediate rotation of the key material for a symmetric key.
func (c Client) RotateKmsKey(ctx context.Context, id UUID) (*RotateKmsKeyResponse, error) {
	path := fmt.Sprintf("/kms-key/%v/rotate", id)

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("RotateKmsKey: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("RotateKmsKey: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("RotateKmsKey: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "rotate-kms-key")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("RotateKmsKey: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("RotateKmsKey: http response: %w", err)
	}

	bodyresp := new(RotateKmsKeyResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("RotateKmsKey: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Schedules a KMS key for deletion after a delay. You can specify a delay of 7-30 days.
func (c Client) ScheduleKmsKeyDeletion(ctx context.Context, id UUID, req ScheduleKmsKeyDeletionRequest) (*ScheduleKmsKeyDeletionResponse, error) {
	path := fmt.Sprintf("/kms-key/%v/schedule-deletion", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("ScheduleKmsKeyDeletion: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("ScheduleKmsKeyDeletion: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ScheduleKmsKeyDeletion: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ScheduleKmsKeyDeletion: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "schedule-kms-key-deletion")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ScheduleKmsKeyDeletion: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ScheduleKmsKeyDeletion: http response: %w", err)
	}

	bodyresp := new(ScheduleKmsKeyDeletionResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ScheduleKmsKeyDeletion: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// [BETA] Returns the live-balance of the current organization.
func (c Client) GetLiveBalance(ctx context.Context) (*LiveBalance, error) {
	path := "/live-balance"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetLiveBalance: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetLiveBalance: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetLiveBalance: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-live-balance")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetLiveBalance: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetLiveBalance: http response: %w", err)
	}

	bodyresp := new(LiveBalance)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetLiveBalance: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ListLoadBalancersResponse struct {
	LoadBalancers []LoadBalancer `json:"load-balancers,omitempty"`
}

// FindLoadBalancer attempts to find an LoadBalancer by nameOrID.
func (l ListLoadBalancersResponse) FindLoadBalancer(nameOrID string) (LoadBalancer, error) {
	var result []LoadBalancer
	for i, elem := range l.LoadBalancers {
		if string(elem.Name) == nameOrID || string(elem.ID) == nameOrID {
			result = append(result, l.LoadBalancers[i])
		}
	}
	if len(result) == 1 {
		return result[0], nil
	}

	if len(result) > 1 {
		return LoadBalancer{}, fmt.Errorf("%q too many found in ListLoadBalancersResponse: %w", nameOrID, ErrConflict)
	}

	return LoadBalancer{}, fmt.Errorf("%q not found in ListLoadBalancersResponse: %w", nameOrID, ErrNotFound)
}

// List Load Balancers
func (c Client) ListLoadBalancers(ctx context.Context) (*ListLoadBalancersResponse, error) {
	path := "/load-balancer"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListLoadBalancers: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListLoadBalancers: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListLoadBalancers: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-load-balancers")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListLoadBalancers: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListLoadBalancers: http response: %w", err)
	}

	bodyresp := new(ListLoadBalancersResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListLoadBalancers: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type CreateLoadBalancerRequest struct {
	// Load Balancer description
	Description string `json:"description,omitempty" validate:"omitempty,lte=255"`
	Labels      Labels `json:"labels,omitempty"`
	// Load Balancer name
	Name string `json:"name" validate:"required,gte=1,lte=255"`
}

// Create a Load Balancer
func (c Client) CreateLoadBalancer(ctx context.Context, req CreateLoadBalancerRequest) (*Operation, error) {
	path := "/load-balancer"

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateLoadBalancer: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateLoadBalancer: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateLoadBalancer: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateLoadBalancer: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-load-balancer")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateLoadBalancer: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateLoadBalancer: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateLoadBalancer: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Delete a Load Balancer
func (c Client) DeleteLoadBalancer(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/load-balancer/%v", id)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteLoadBalancer: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteLoadBalancer: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteLoadBalancer: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-load-balancer")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteLoadBalancer: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteLoadBalancer: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteLoadBalancer: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Retrieve Load Balancer details
func (c Client) GetLoadBalancer(ctx context.Context, id UUID) (*LoadBalancer, error) {
	path := fmt.Sprintf("/load-balancer/%v", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetLoadBalancer: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetLoadBalancer: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetLoadBalancer: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-load-balancer")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetLoadBalancer: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetLoadBalancer: http response: %w", err)
	}

	bodyresp := new(LoadBalancer)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetLoadBalancer: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type UpdateLoadBalancerRequest struct {
	// Load Balancer description
	Description string `json:"description,omitempty" validate:"omitempty,lte=255"`
	Labels      Labels `json:"labels,omitempty"`
	// Load Balancer name
	Name string `json:"name,omitempty" validate:"omitempty,gte=1,lte=255"`
}

// Update a Load Balancer
func (c Client) UpdateLoadBalancer(ctx context.Context, id UUID, req UpdateLoadBalancerRequest) (*Operation, error) {
	path := fmt.Sprintf("/load-balancer/%v", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateLoadBalancer: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateLoadBalancer: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateLoadBalancer: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateLoadBalancer: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-load-balancer")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateLoadBalancer: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateLoadBalancer: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateLoadBalancer: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type AddServiceToLoadBalancerRequestProtocol string

const (
	AddServiceToLoadBalancerRequestProtocolTCP AddServiceToLoadBalancerRequestProtocol = "tcp"
	AddServiceToLoadBalancerRequestProtocolUDP AddServiceToLoadBalancerRequestProtocol = "udp"
)

type AddServiceToLoadBalancerRequestStrategy string

const (
	AddServiceToLoadBalancerRequestStrategyRoundRobin AddServiceToLoadBalancerRequestStrategy = "round-robin"
	AddServiceToLoadBalancerRequestStrategyMaglevHash AddServiceToLoadBalancerRequestStrategy = "maglev-hash"
	AddServiceToLoadBalancerRequestStrategySourceHash AddServiceToLoadBalancerRequestStrategy = "source-hash"
)

type AddServiceToLoadBalancerRequest struct {
	// Load Balancer Service description
	Description string `json:"description,omitempty" validate:"omitempty,lte=255"`
	// Load Balancer Service healthcheck
	Healthcheck *LoadBalancerServiceHealthcheck `json:"healthcheck" validate:"required"`
	// Instance Pool
	InstancePool *InstancePool `json:"instance-pool" validate:"required"`
	// Load Balancer Service name
	Name string `json:"name" validate:"required,gte=1,lte=255"`
	// Port exposed on the Load Balancer's public IP
	Port int64 `json:"port" validate:"required,gte=1,lte=65535"`
	// Network traffic protocol
	Protocol AddServiceToLoadBalancerRequestProtocol `json:"protocol" validate:"required"`
	// Load balancing strategy
	Strategy AddServiceToLoadBalancerRequestStrategy `json:"strategy" validate:"required"`
	// Port on which the network traffic will be forwarded to on the receiving instance
	TargetPort int64 `json:"target-port" validate:"required,gte=1,lte=65535"`
}

// Add a Load Balancer Service
func (c Client) AddServiceToLoadBalancer(ctx context.Context, id UUID, req AddServiceToLoadBalancerRequest) (*Operation, error) {
	path := fmt.Sprintf("/load-balancer/%v/service", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("AddServiceToLoadBalancer: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("AddServiceToLoadBalancer: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("AddServiceToLoadBalancer: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("AddServiceToLoadBalancer: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "add-service-to-load-balancer")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("AddServiceToLoadBalancer: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("AddServiceToLoadBalancer: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("AddServiceToLoadBalancer: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Delete a Load Balancer Service
func (c Client) DeleteLoadBalancerService(ctx context.Context, id UUID, serviceID UUID) (*Operation, error) {
	path := fmt.Sprintf("/load-balancer/%v/service/%v", id, serviceID)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteLoadBalancerService: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteLoadBalancerService: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteLoadBalancerService: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-load-balancer-service")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteLoadBalancerService: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteLoadBalancerService: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteLoadBalancerService: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Retrieve Load Balancer Service details
func (c Client) GetLoadBalancerService(ctx context.Context, id UUID, serviceID UUID) (*LoadBalancerService, error) {
	path := fmt.Sprintf("/load-balancer/%v/service/%v", id, serviceID)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetLoadBalancerService: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetLoadBalancerService: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetLoadBalancerService: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-load-balancer-service")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetLoadBalancerService: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetLoadBalancerService: http response: %w", err)
	}

	bodyresp := new(LoadBalancerService)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetLoadBalancerService: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type UpdateLoadBalancerServiceRequestProtocol string

const (
	UpdateLoadBalancerServiceRequestProtocolTCP UpdateLoadBalancerServiceRequestProtocol = "tcp"
	UpdateLoadBalancerServiceRequestProtocolUDP UpdateLoadBalancerServiceRequestProtocol = "udp"
)

type UpdateLoadBalancerServiceRequestStrategy string

const (
	UpdateLoadBalancerServiceRequestStrategyRoundRobin UpdateLoadBalancerServiceRequestStrategy = "round-robin"
	UpdateLoadBalancerServiceRequestStrategyMaglevHash UpdateLoadBalancerServiceRequestStrategy = "maglev-hash"
	UpdateLoadBalancerServiceRequestStrategySourceHash UpdateLoadBalancerServiceRequestStrategy = "source-hash"
)

type UpdateLoadBalancerServiceRequest struct {
	// Load Balancer Service description
	Description string `json:"description,omitempty" validate:"omitempty,lte=255"`
	// Load Balancer Service healthcheck
	Healthcheck *LoadBalancerServiceHealthcheck `json:"healthcheck,omitempty"`
	// Load Balancer Service name
	Name string `json:"name,omitempty" validate:"omitempty,lte=255"`
	// Port exposed on the Load Balancer's public IP
	Port int64 `json:"port,omitempty" validate:"omitempty,gte=1,lte=65535"`
	// Network traffic protocol
	Protocol UpdateLoadBalancerServiceRequestProtocol `json:"protocol,omitempty"`
	// Load balancing strategy
	Strategy UpdateLoadBalancerServiceRequestStrategy `json:"strategy,omitempty"`
	// Port on which the network traffic will be forwarded to on the receiving instance
	TargetPort int64 `json:"target-port,omitempty" validate:"omitempty,gte=1,lte=65535"`
}

// Update a Load Balancer Service
func (c Client) UpdateLoadBalancerService(ctx context.Context, id UUID, serviceID UUID, req UpdateLoadBalancerServiceRequest) (*Operation, error) {
	path := fmt.Sprintf("/load-balancer/%v/service/%v", id, serviceID)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateLoadBalancerService: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateLoadBalancerService: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateLoadBalancerService: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateLoadBalancerService: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-load-balancer-service")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateLoadBalancerService: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateLoadBalancerService: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateLoadBalancerService: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ResetLoadBalancerServiceFieldField string

const (
	ResetLoadBalancerServiceFieldFieldDescription ResetLoadBalancerServiceFieldField = "description"
)

// Reset a Load Balancer Service field to its default value
func (c Client) ResetLoadBalancerServiceField(ctx context.Context, id UUID, serviceID UUID, field ResetLoadBalancerServiceFieldField) (*Operation, error) {
	path := fmt.Sprintf("/load-balancer/%v/service/%v/%v", id, serviceID, field)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ResetLoadBalancerServiceField: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ResetLoadBalancerServiceField: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ResetLoadBalancerServiceField: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reset-load-balancer-service-field")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ResetLoadBalancerServiceField: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ResetLoadBalancerServiceField: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ResetLoadBalancerServiceField: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ResetLoadBalancerFieldField string

const (
	ResetLoadBalancerFieldFieldDescription ResetLoadBalancerFieldField = "description"
	ResetLoadBalancerFieldFieldLabels      ResetLoadBalancerFieldField = "labels"
)

// Reset a Load Balancer field to its default value
func (c Client) ResetLoadBalancerField(ctx context.Context, id UUID, field ResetLoadBalancerFieldField) (*Operation, error) {
	path := fmt.Sprintf("/load-balancer/%v/%v", id, field)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ResetLoadBalancerField: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ResetLoadBalancerField: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ResetLoadBalancerField: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reset-load-balancer-field")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ResetLoadBalancerField: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ResetLoadBalancerField: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ResetLoadBalancerField: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Retrieve Operation details
func (c Client) GetOperation(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/operation/%v", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetOperation: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetOperation: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetOperation: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-operation")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetOperation: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetOperation: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetOperation: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Retrieve an organization
func (c Client) GetOrganization(ctx context.Context) (*Organization, error) {
	path := "/organization"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetOrganization: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetOrganization: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetOrganization: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-organization")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetOrganization: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetOrganization: http response: %w", err)
	}

	bodyresp := new(Organization)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetOrganization: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ListPrivateNetworksResponse struct {
	PrivateNetworks []PrivateNetwork `json:"private-networks,omitempty"`
}

// FindPrivateNetwork attempts to find an PrivateNetwork by nameOrID.
func (l ListPrivateNetworksResponse) FindPrivateNetwork(nameOrID string) (PrivateNetwork, error) {
	var result []PrivateNetwork
	for i, elem := range l.PrivateNetworks {
		if string(elem.Name) == nameOrID || string(elem.ID) == nameOrID {
			result = append(result, l.PrivateNetworks[i])
		}
	}
	if len(result) == 1 {
		return result[0], nil
	}

	if len(result) > 1 {
		return PrivateNetwork{}, fmt.Errorf("%q too many found in ListPrivateNetworksResponse: %w", nameOrID, ErrConflict)
	}

	return PrivateNetwork{}, fmt.Errorf("%q not found in ListPrivateNetworksResponse: %w", nameOrID, ErrNotFound)
}

// List Private Networks
func (c Client) ListPrivateNetworks(ctx context.Context) (*ListPrivateNetworksResponse, error) {
	path := "/private-network"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListPrivateNetworks: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListPrivateNetworks: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListPrivateNetworks: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-private-networks")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListPrivateNetworks: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListPrivateNetworks: http response: %w", err)
	}

	bodyresp := new(ListPrivateNetworksResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListPrivateNetworks: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type CreatePrivateNetworkRequest struct {
	// Private Network description
	Description string `json:"description,omitempty" validate:"omitempty,lte=255"`
	// Private Network end IP address
	EndIP  net.IP `json:"end-ip,omitempty"`
	Labels Labels `json:"labels,omitempty"`
	// Private Network name
	Name string `json:"name" validate:"required,gte=1,lte=255"`
	// Private Network netmask
	Netmask net.IP `json:"netmask,omitempty"`
	// Private Network DHCP Options
	Options *PrivateNetworkOptions `json:"options,omitempty"`
	// Private Network start IP address
	StartIP net.IP `json:"start-ip,omitempty"`
}

// Create a Private Network
func (c Client) CreatePrivateNetwork(ctx context.Context, req CreatePrivateNetworkRequest) (*Operation, error) {
	path := "/private-network"

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreatePrivateNetwork: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreatePrivateNetwork: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreatePrivateNetwork: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreatePrivateNetwork: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-private-network")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreatePrivateNetwork: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreatePrivateNetwork: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreatePrivateNetwork: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Delete a Private Network
func (c Client) DeletePrivateNetwork(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/private-network/%v", id)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeletePrivateNetwork: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeletePrivateNetwork: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeletePrivateNetwork: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-private-network")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeletePrivateNetwork: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeletePrivateNetwork: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeletePrivateNetwork: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Retrieve Private Network details
func (c Client) GetPrivateNetwork(ctx context.Context, id UUID) (*PrivateNetwork, error) {
	path := fmt.Sprintf("/private-network/%v", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetPrivateNetwork: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetPrivateNetwork: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetPrivateNetwork: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-private-network")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetPrivateNetwork: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetPrivateNetwork: http response: %w", err)
	}

	bodyresp := new(PrivateNetwork)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetPrivateNetwork: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type UpdatePrivateNetworkRequest struct {
	// Private Network description
	Description string `json:"description,omitempty" validate:"omitempty,lte=255"`
	// Private Network end IP address
	EndIP  net.IP `json:"end-ip,omitempty"`
	Labels Labels `json:"labels,omitempty"`
	// Private Network name
	Name string `json:"name,omitempty" validate:"omitempty,gte=1,lte=255"`
	// Private Network netmask
	Netmask net.IP `json:"netmask,omitempty"`
	// Private Network DHCP Options
	Options *PrivateNetworkOptions `json:"options,omitempty"`
	// Private Network start IP address
	StartIP net.IP `json:"start-ip,omitempty"`
}

// Update a Private Network
func (c Client) UpdatePrivateNetwork(ctx context.Context, id UUID, req UpdatePrivateNetworkRequest) (*Operation, error) {
	path := fmt.Sprintf("/private-network/%v", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdatePrivateNetwork: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdatePrivateNetwork: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdatePrivateNetwork: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdatePrivateNetwork: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-private-network")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdatePrivateNetwork: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdatePrivateNetwork: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdatePrivateNetwork: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ResetPrivateNetworkFieldField string

const (
	ResetPrivateNetworkFieldFieldLabels ResetPrivateNetworkFieldField = "labels"
)

// Reset Private Network field
func (c Client) ResetPrivateNetworkField(ctx context.Context, id UUID, field ResetPrivateNetworkFieldField) (*Operation, error) {
	path := fmt.Sprintf("/private-network/%v/%v", id, field)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ResetPrivateNetworkField: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ResetPrivateNetworkField: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ResetPrivateNetworkField: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reset-private-network-field")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ResetPrivateNetworkField: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ResetPrivateNetworkField: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ResetPrivateNetworkField: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Compute instance
type AttachInstanceToPrivateNetworkRequestInstance struct {
	// Instance ID
	ID UUID `json:"id,omitempty"`
}

type AttachInstanceToPrivateNetworkRequest struct {
	// Compute instance
	Instance *AttachInstanceToPrivateNetworkRequestInstance `json:"instance" validate:"required"`
	// Static IP address lease for the corresponding network interface
	IP net.IP `json:"ip,omitempty"`
}

// Attach a Compute instance to a Private Network
func (c Client) AttachInstanceToPrivateNetwork(ctx context.Context, id UUID, req AttachInstanceToPrivateNetworkRequest) (*Operation, error) {
	path := fmt.Sprintf("/private-network/%v:attach", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("AttachInstanceToPrivateNetwork: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("AttachInstanceToPrivateNetwork: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("AttachInstanceToPrivateNetwork: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("AttachInstanceToPrivateNetwork: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "attach-instance-to-private-network")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("AttachInstanceToPrivateNetwork: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("AttachInstanceToPrivateNetwork: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("AttachInstanceToPrivateNetwork: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type DetachInstanceFromPrivateNetworkRequest struct {
	// Instance
	Instance *Instance `json:"instance" validate:"required"`
}

// Detach a Compute instance from a Private Network
func (c Client) DetachInstanceFromPrivateNetwork(ctx context.Context, id UUID, req DetachInstanceFromPrivateNetworkRequest) (*Operation, error) {
	path := fmt.Sprintf("/private-network/%v:detach", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("DetachInstanceFromPrivateNetwork: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("DetachInstanceFromPrivateNetwork: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DetachInstanceFromPrivateNetwork: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DetachInstanceFromPrivateNetwork: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "detach-instance-from-private-network")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DetachInstanceFromPrivateNetwork: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DetachInstanceFromPrivateNetwork: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DetachInstanceFromPrivateNetwork: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type UpdatePrivateNetworkInstanceIPRequestInstance struct {
	// Instance ID
	ID UUID `json:"id" validate:"required"`
}

type UpdatePrivateNetworkInstanceIPRequest struct {
	Instance *UpdatePrivateNetworkInstanceIPRequestInstance `json:"instance,omitempty"`
	// Static IP address lease for the corresponding network interface
	IP net.IP `json:"ip,omitempty"`
}

// Update the IP address of an instance attached to a managed private network
func (c Client) UpdatePrivateNetworkInstanceIP(ctx context.Context, id UUID, req UpdatePrivateNetworkInstanceIPRequest) (*Operation, error) {
	path := fmt.Sprintf("/private-network/%v:update-ip", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdatePrivateNetworkInstanceIP: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdatePrivateNetworkInstanceIP: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdatePrivateNetworkInstanceIP: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdatePrivateNetworkInstanceIP: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-private-network-instance-ip")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdatePrivateNetworkInstanceIP: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdatePrivateNetworkInstanceIP: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdatePrivateNetworkInstanceIP: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ListQuotasResponse struct {
	Quotas []Quota `json:"quotas,omitempty"`
}

// List Organization Quotas
func (c Client) ListQuotas(ctx context.Context) (*ListQuotasResponse, error) {
	path := "/quota"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListQuotas: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListQuotas: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListQuotas: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-quotas")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListQuotas: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListQuotas: http response: %w", err)
	}

	bodyresp := new(ListQuotasResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListQuotas: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Retrieve Resource Quota
func (c Client) GetQuota(ctx context.Context, entity string) (*Quota, error) {
	path := fmt.Sprintf("/quota/%v", entity)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetQuota: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetQuota: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetQuota: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-quota")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetQuota: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetQuota: http response: %w", err)
	}

	bodyresp := new(Quota)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetQuota: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Delete the PTR DNS record for an elastic IP
func (c Client) DeleteReverseDNSElasticIP(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/reverse-dns/elastic-ip/%v", id)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteReverseDNSElasticIP: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteReverseDNSElasticIP: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteReverseDNSElasticIP: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-reverse-dns-elastic-ip")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteReverseDNSElasticIP: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteReverseDNSElasticIP: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteReverseDNSElasticIP: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Query the PTR DNS records for an elastic IP
func (c Client) GetReverseDNSElasticIP(ctx context.Context, id UUID) (*ReverseDNSRecord, error) {
	path := fmt.Sprintf("/reverse-dns/elastic-ip/%v", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetReverseDNSElasticIP: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetReverseDNSElasticIP: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetReverseDNSElasticIP: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-reverse-dns-elastic-ip")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetReverseDNSElasticIP: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetReverseDNSElasticIP: http response: %w", err)
	}

	bodyresp := new(ReverseDNSRecord)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetReverseDNSElasticIP: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type UpdateReverseDNSElasticIPRequest struct {
	DomainName string `json:"domain-name,omitempty" validate:"omitempty,gte=1,lte=253"`
}

// Update/Create the PTR DNS record for an elastic IP
func (c Client) UpdateReverseDNSElasticIP(ctx context.Context, id UUID, req UpdateReverseDNSElasticIPRequest) (*Operation, error) {
	path := fmt.Sprintf("/reverse-dns/elastic-ip/%v", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateReverseDNSElasticIP: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateReverseDNSElasticIP: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateReverseDNSElasticIP: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateReverseDNSElasticIP: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-reverse-dns-elastic-ip")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateReverseDNSElasticIP: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateReverseDNSElasticIP: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateReverseDNSElasticIP: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Delete the PTR DNS record for an instance
func (c Client) DeleteReverseDNSInstance(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/reverse-dns/instance/%v", id)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteReverseDNSInstance: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteReverseDNSInstance: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteReverseDNSInstance: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-reverse-dns-instance")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteReverseDNSInstance: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteReverseDNSInstance: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteReverseDNSInstance: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Query the PTR DNS records for an instance
func (c Client) GetReverseDNSInstance(ctx context.Context, id UUID) (*ReverseDNSRecord, error) {
	path := fmt.Sprintf("/reverse-dns/instance/%v", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetReverseDNSInstance: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetReverseDNSInstance: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetReverseDNSInstance: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-reverse-dns-instance")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetReverseDNSInstance: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetReverseDNSInstance: http response: %w", err)
	}

	bodyresp := new(ReverseDNSRecord)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetReverseDNSInstance: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type UpdateReverseDNSInstanceRequest struct {
	DomainName string `json:"domain-name,omitempty" validate:"omitempty,gte=1,lte=253"`
}

// Update/Create the PTR DNS record for an instance
func (c Client) UpdateReverseDNSInstance(ctx context.Context, id UUID, req UpdateReverseDNSInstanceRequest) (*Operation, error) {
	path := fmt.Sprintf("/reverse-dns/instance/%v", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateReverseDNSInstance: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateReverseDNSInstance: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateReverseDNSInstance: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateReverseDNSInstance: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-reverse-dns-instance")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateReverseDNSInstance: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateReverseDNSInstance: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateReverseDNSInstance: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ListSecurityGroupsResponse struct {
	SecurityGroups []SecurityGroup `json:"security-groups,omitempty"`
}

// FindSecurityGroup attempts to find an SecurityGroup by nameOrID.
func (l ListSecurityGroupsResponse) FindSecurityGroup(nameOrID string) (SecurityGroup, error) {
	var result []SecurityGroup
	for i, elem := range l.SecurityGroups {
		if string(elem.Name) == nameOrID || string(elem.ID) == nameOrID {
			result = append(result, l.SecurityGroups[i])
		}
	}
	if len(result) == 1 {
		return result[0], nil
	}

	if len(result) > 1 {
		return SecurityGroup{}, fmt.Errorf("%q too many found in ListSecurityGroupsResponse: %w", nameOrID, ErrConflict)
	}

	return SecurityGroup{}, fmt.Errorf("%q not found in ListSecurityGroupsResponse: %w", nameOrID, ErrNotFound)
}

type ListSecurityGroupsVisibility string

const (
	ListSecurityGroupsVisibilityPrivate ListSecurityGroupsVisibility = "private"
	ListSecurityGroupsVisibilityPublic  ListSecurityGroupsVisibility = "public"
)

type ListSecurityGroupsOpt func(url.Values)

func ListSecurityGroupsWithVisibility(visibility ListSecurityGroupsVisibility) ListSecurityGroupsOpt {
	return func(q url.Values) {
		q.Add("visibility", fmt.Sprint(visibility))
	}
}

// Lists security groups. When visibility is set to public, lists public security groups.
// Public security groups are objects maintained by Exoscale which contain source addresses for
// relevant services hosted by Exoscale. They can be used a source in ingress rules and as a destination
// in egress rules.
func (c Client) ListSecurityGroups(ctx context.Context, opts ...ListSecurityGroupsOpt) (*ListSecurityGroupsResponse, error) {
	path := "/security-group"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListSecurityGroups: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if len(opts) > 0 {
		q := request.URL.Query()
		for _, opt := range opts {
			opt(q)
		}
		request.URL.RawQuery = q.Encode()
	}

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListSecurityGroups: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListSecurityGroups: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-security-groups")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListSecurityGroups: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListSecurityGroups: http response: %w", err)
	}

	bodyresp := new(ListSecurityGroupsResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListSecurityGroups: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type CreateSecurityGroupRequest struct {
	// Security Group description
	Description string `json:"description,omitempty" validate:"omitempty,lte=255"`
	// Security Group name
	Name string `json:"name" validate:"required,gte=1,lte=255"`
}

// Create a Security Group
func (c Client) CreateSecurityGroup(ctx context.Context, req CreateSecurityGroupRequest) (*Operation, error) {
	path := "/security-group"

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateSecurityGroup: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateSecurityGroup: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateSecurityGroup: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateSecurityGroup: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-security-group")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateSecurityGroup: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateSecurityGroup: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateSecurityGroup: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Delete a Security Group
func (c Client) DeleteSecurityGroup(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/security-group/%v", id)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteSecurityGroup: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteSecurityGroup: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteSecurityGroup: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-security-group")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteSecurityGroup: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteSecurityGroup: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteSecurityGroup: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Retrieve Security Group details
func (c Client) GetSecurityGroup(ctx context.Context, id UUID) (*SecurityGroup, error) {
	path := fmt.Sprintf("/security-group/%v", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetSecurityGroup: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetSecurityGroup: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetSecurityGroup: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-security-group")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetSecurityGroup: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetSecurityGroup: http response: %w", err)
	}

	bodyresp := new(SecurityGroup)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetSecurityGroup: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type AddRuleToSecurityGroupRequestFlowDirection string

const (
	AddRuleToSecurityGroupRequestFlowDirectionIngress AddRuleToSecurityGroupRequestFlowDirection = "ingress"
	AddRuleToSecurityGroupRequestFlowDirectionEgress  AddRuleToSecurityGroupRequestFlowDirection = "egress"
)

// ICMP details (default: -1 (ANY))
type AddRuleToSecurityGroupRequestICMP struct {
	Code *int64 `json:"code,omitempty" validate:"omitempty,gte=-1,lte=254"`
	Type *int64 `json:"type,omitempty" validate:"omitempty,gte=-1,lte=254"`
}

type AddRuleToSecurityGroupRequestProtocol string

const (
	AddRuleToSecurityGroupRequestProtocolTCP    AddRuleToSecurityGroupRequestProtocol = "tcp"
	AddRuleToSecurityGroupRequestProtocolEsp    AddRuleToSecurityGroupRequestProtocol = "esp"
	AddRuleToSecurityGroupRequestProtocolICMP   AddRuleToSecurityGroupRequestProtocol = "icmp"
	AddRuleToSecurityGroupRequestProtocolUDP    AddRuleToSecurityGroupRequestProtocol = "udp"
	AddRuleToSecurityGroupRequestProtocolGre    AddRuleToSecurityGroupRequestProtocol = "gre"
	AddRuleToSecurityGroupRequestProtocolAh     AddRuleToSecurityGroupRequestProtocol = "ah"
	AddRuleToSecurityGroupRequestProtocolIpip   AddRuleToSecurityGroupRequestProtocol = "ipip"
	AddRuleToSecurityGroupRequestProtocolIcmpv6 AddRuleToSecurityGroupRequestProtocol = "icmpv6"
)

type AddRuleToSecurityGroupRequest struct {
	// Security Group rule description
	Description string `json:"description,omitempty" validate:"omitempty,lte=255"`
	// End port of the range
	EndPort int64 `json:"end-port,omitempty" validate:"omitempty,gte=1,lte=65535"`
	// Network flow direction to match
	FlowDirection AddRuleToSecurityGroupRequestFlowDirection `json:"flow-direction" validate:"required"`
	// ICMP details (default: -1 (ANY))
	ICMP *AddRuleToSecurityGroupRequestICMP `json:"icmp,omitempty"`
	// CIDR-formatted network allowed
	Network string `json:"network,omitempty"`
	// Network protocol
	Protocol AddRuleToSecurityGroupRequestProtocol `json:"protocol" validate:"required"`
	// Security Group
	SecurityGroup *SecurityGroupResource `json:"security-group,omitempty"`
	// Start port of the range
	StartPort int64 `json:"start-port,omitempty" validate:"omitempty,gte=1,lte=65535"`
}

// Create a Security Group rule
func (c Client) AddRuleToSecurityGroup(ctx context.Context, id UUID, req AddRuleToSecurityGroupRequest) (*Operation, error) {
	path := fmt.Sprintf("/security-group/%v/rules", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("AddRuleToSecurityGroup: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("AddRuleToSecurityGroup: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("AddRuleToSecurityGroup: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("AddRuleToSecurityGroup: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "add-rule-to-security-group")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("AddRuleToSecurityGroup: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("AddRuleToSecurityGroup: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("AddRuleToSecurityGroup: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Delete a Security Group rule
func (c Client) DeleteRuleFromSecurityGroup(ctx context.Context, id UUID, ruleID UUID) (*Operation, error) {
	path := fmt.Sprintf("/security-group/%v/rules/%v", id, ruleID)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteRuleFromSecurityGroup: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteRuleFromSecurityGroup: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteRuleFromSecurityGroup: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-rule-from-security-group")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteRuleFromSecurityGroup: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteRuleFromSecurityGroup: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteRuleFromSecurityGroup: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type AddExternalSourceToSecurityGroupRequest struct {
	// CIDR-formatted network to add
	Cidr string `json:"cidr" validate:"required"`
}

// Add an external source as a member of a Security Group
func (c Client) AddExternalSourceToSecurityGroup(ctx context.Context, id UUID, req AddExternalSourceToSecurityGroupRequest) (*Operation, error) {
	path := fmt.Sprintf("/security-group/%v:add-source", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("AddExternalSourceToSecurityGroup: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("AddExternalSourceToSecurityGroup: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("AddExternalSourceToSecurityGroup: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("AddExternalSourceToSecurityGroup: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "add-external-source-to-security-group")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("AddExternalSourceToSecurityGroup: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("AddExternalSourceToSecurityGroup: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("AddExternalSourceToSecurityGroup: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type AttachInstanceToSecurityGroupRequest struct {
	// Instance
	Instance *Instance `json:"instance" validate:"required"`
}

// Attach a Compute instance to a Security Group
func (c Client) AttachInstanceToSecurityGroup(ctx context.Context, id UUID, req AttachInstanceToSecurityGroupRequest) (*Operation, error) {
	path := fmt.Sprintf("/security-group/%v:attach", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("AttachInstanceToSecurityGroup: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("AttachInstanceToSecurityGroup: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("AttachInstanceToSecurityGroup: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("AttachInstanceToSecurityGroup: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "attach-instance-to-security-group")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("AttachInstanceToSecurityGroup: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("AttachInstanceToSecurityGroup: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("AttachInstanceToSecurityGroup: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type DetachInstanceFromSecurityGroupRequest struct {
	// Instance
	Instance *Instance `json:"instance" validate:"required"`
}

// Detach a Compute instance from a Security Group
func (c Client) DetachInstanceFromSecurityGroup(ctx context.Context, id UUID, req DetachInstanceFromSecurityGroupRequest) (*Operation, error) {
	path := fmt.Sprintf("/security-group/%v:detach", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("DetachInstanceFromSecurityGroup: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("DetachInstanceFromSecurityGroup: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DetachInstanceFromSecurityGroup: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DetachInstanceFromSecurityGroup: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "detach-instance-from-security-group")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DetachInstanceFromSecurityGroup: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DetachInstanceFromSecurityGroup: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DetachInstanceFromSecurityGroup: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type RemoveExternalSourceFromSecurityGroupRequest struct {
	// CIDR-formatted network to remove
	Cidr string `json:"cidr" validate:"required"`
}

// Remove an external source from a Security Group
func (c Client) RemoveExternalSourceFromSecurityGroup(ctx context.Context, id UUID, req RemoveExternalSourceFromSecurityGroupRequest) (*Operation, error) {
	path := fmt.Sprintf("/security-group/%v:remove-source", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("RemoveExternalSourceFromSecurityGroup: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("RemoveExternalSourceFromSecurityGroup: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("RemoveExternalSourceFromSecurityGroup: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("RemoveExternalSourceFromSecurityGroup: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "remove-external-source-from-security-group")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("RemoveExternalSourceFromSecurityGroup: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("RemoveExternalSourceFromSecurityGroup: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("RemoveExternalSourceFromSecurityGroup: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ListSKSClustersResponse struct {
	SKSClusters []SKSCluster `json:"sks-clusters,omitempty"`
}

// FindSKSCluster attempts to find an SKSCluster by nameOrID.
func (l ListSKSClustersResponse) FindSKSCluster(nameOrID string) (SKSCluster, error) {
	var result []SKSCluster
	for i, elem := range l.SKSClusters {
		if string(elem.Name) == nameOrID || string(elem.ID) == nameOrID {
			result = append(result, l.SKSClusters[i])
		}
	}
	if len(result) == 1 {
		return result[0], nil
	}

	if len(result) > 1 {
		return SKSCluster{}, fmt.Errorf("%q too many found in ListSKSClustersResponse: %w", nameOrID, ErrConflict)
	}

	return SKSCluster{}, fmt.Errorf("%q not found in ListSKSClustersResponse: %w", nameOrID, ErrNotFound)
}

// List SKS clusters
func (c Client) ListSKSClusters(ctx context.Context) (*ListSKSClustersResponse, error) {
	path := "/sks-cluster"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListSKSClusters: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListSKSClusters: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListSKSClusters: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-sks-clusters")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListSKSClusters: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListSKSClusters: http response: %w", err)
	}

	bodyresp := new(ListSKSClustersResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListSKSClusters: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type CreateSKSClusterRequestCni string

const (
	CreateSKSClusterRequestCniCalico CreateSKSClusterRequestCni = "calico"
	CreateSKSClusterRequestCniCilium CreateSKSClusterRequestCni = "cilium"
)

type CreateSKSClusterRequestLevel string

const (
	CreateSKSClusterRequestLevelStarter CreateSKSClusterRequestLevel = "starter"
	CreateSKSClusterRequestLevelPro     CreateSKSClusterRequestLevel = "pro"
)

type CreateSKSClusterRequest struct {
	// Cluster addons
	Addons []string `json:"addons,omitempty"`
	// Kubernetes Audit parameters
	Audit *SKSAuditCreate `json:"audit,omitempty"`
	// Enable auto upgrade of the control plane to the latest patch version available
	AutoUpgrade *bool `json:"auto-upgrade,omitempty"`
	// Cluster CNI
	Cni CreateSKSClusterRequestCni `json:"cni,omitempty"`
	// Creates an ad-hoc security group based on the choice of the selected CNI
	CreateDefaultSecurityGroup *bool `json:"create-default-security-group,omitempty"`
	// Cluster description
	Description *string `json:"description,omitempty" validate:"omitempty,lte=255"`
	// Indicates whether to deploy the Kubernetes network proxy. When unspecified, defaults to `true` unless Cilium CNI is selected
	EnableKubeProxy *bool `json:"enable-kube-proxy,omitempty"`
	// A list of Kubernetes-only Alpha features to enable for API server component
	FeatureGates []string         `json:"feature-gates,omitempty"`
	Labels       SKSClusterLabels `json:"labels,omitempty"`
	// Cluster service level
	Level CreateSKSClusterRequestLevel `json:"level" validate:"required"`
	// Cluster name
	Name string `json:"name" validate:"required,gte=1,lte=255"`
	// EXPERIMENTAL: Cluster networking configuration.
	Networking *Networking `json:"networking,omitempty"`
	// SKS Cluster OpenID config map
	Oidc *SKSOidc `json:"oidc,omitempty"`
	// Control plane Kubernetes version
	Version string `json:"version" validate:"required"`
}

// Create an SKS cluster
func (c Client) CreateSKSCluster(ctx context.Context, req CreateSKSClusterRequest) (*Operation, error) {
	path := "/sks-cluster"

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateSKSCluster: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateSKSCluster: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateSKSCluster: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateSKSCluster: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-sks-cluster")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateSKSCluster: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateSKSCluster: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateSKSCluster: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// This operation returns the deprecated resources for a given cluster
func (c Client) ListSKSClusterDeprecatedResources(ctx context.Context, id UUID) ([]SKSClusterDeprecatedResource, error) {
	path := fmt.Sprintf("/sks-cluster-deprecated-resources/%v", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListSKSClusterDeprecatedResources: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListSKSClusterDeprecatedResources: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListSKSClusterDeprecatedResources: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-sks-cluster-deprecated-resources")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListSKSClusterDeprecatedResources: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListSKSClusterDeprecatedResources: http response: %w", err)
	}

	bodyresp := []SKSClusterDeprecatedResource{}
	if err := prepareJSONResponse(response, &bodyresp); err != nil {
		return nil, fmt.Errorf("ListSKSClusterDeprecatedResources: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type GenerateSKSClusterKubeconfigResponse struct {
	Kubeconfig string `json:"kubeconfig,omitempty"`
}

// This operation returns a Kubeconfig file encoded in base64.
func (c Client) GenerateSKSClusterKubeconfig(ctx context.Context, id UUID, req SKSKubeconfigRequest) (*GenerateSKSClusterKubeconfigResponse, error) {
	path := fmt.Sprintf("/sks-cluster-kubeconfig/%v", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("GenerateSKSClusterKubeconfig: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("GenerateSKSClusterKubeconfig: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GenerateSKSClusterKubeconfig: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GenerateSKSClusterKubeconfig: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "generate-sks-cluster-kubeconfig")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GenerateSKSClusterKubeconfig: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GenerateSKSClusterKubeconfig: http response: %w", err)
	}

	bodyresp := new(GenerateSKSClusterKubeconfigResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GenerateSKSClusterKubeconfig: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ListSKSClusterVersionsResponse struct {
	SKSClusterVersions []string `json:"sks-cluster-versions,omitempty"`
}

type ListSKSClusterVersionsOpt func(url.Values)

func ListSKSClusterVersionsWithIncludeDeprecated(includeDeprecated string) ListSKSClusterVersionsOpt {
	return func(q url.Values) {
		q.Add("include-deprecated", fmt.Sprint(includeDeprecated))
	}
}

// List available versions for SKS clusters
func (c Client) ListSKSClusterVersions(ctx context.Context, opts ...ListSKSClusterVersionsOpt) (*ListSKSClusterVersionsResponse, error) {
	path := "/sks-cluster-version"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListSKSClusterVersions: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if len(opts) > 0 {
		q := request.URL.Query()
		for _, opt := range opts {
			opt(q)
		}
		request.URL.RawQuery = q.Encode()
	}

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListSKSClusterVersions: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListSKSClusterVersions: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-sks-cluster-versions")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListSKSClusterVersions: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListSKSClusterVersions: http response: %w", err)
	}

	bodyresp := new(ListSKSClusterVersionsResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListSKSClusterVersions: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Delete an SKS cluster
func (c Client) DeleteSKSCluster(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/sks-cluster/%v", id)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteSKSCluster: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteSKSCluster: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteSKSCluster: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-sks-cluster")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteSKSCluster: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteSKSCluster: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteSKSCluster: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Retrieve SKS cluster details
func (c Client) GetSKSCluster(ctx context.Context, id UUID) (*SKSCluster, error) {
	path := fmt.Sprintf("/sks-cluster/%v", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetSKSCluster: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetSKSCluster: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetSKSCluster: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-sks-cluster")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetSKSCluster: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetSKSCluster: http response: %w", err)
	}

	bodyresp := new(SKSCluster)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetSKSCluster: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type UpdateSKSClusterRequest struct {
	// Cluster addons
	Addons []string `json:"addons,omitempty"`
	// Kubernetes Audit parameters
	Audit *SKSAuditUpdate `json:"audit,omitempty"`
	// Enable auto upgrade of the control plane to the latest patch version available
	AutoUpgrade *bool `json:"auto-upgrade,omitempty"`
	// Cluster description
	Description *string `json:"description,omitempty" validate:"omitempty,lte=255"`
	// Add or remove the operators certificate authority (CA) from the list of trusted CAs of the api server. The default value is true
	EnableOperatorsCA *bool `json:"enable-operators-ca,omitempty"`
	// A list of Kubernetes-only Alpha features to enable for API server component
	FeatureGates []string         `json:"feature-gates"`
	Labels       SKSClusterLabels `json:"labels,omitempty"`
	// Cluster name
	Name string `json:"name,omitempty" validate:"omitempty,gte=1,lte=255"`
	// SKS Cluster OpenID config map
	Oidc *SKSOidc `json:"oidc"`
}

// Update an SKS cluster
func (c Client) UpdateSKSCluster(ctx context.Context, id UUID, req UpdateSKSClusterRequest) (*Operation, error) {
	path := fmt.Sprintf("/sks-cluster/%v", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateSKSCluster: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateSKSCluster: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateSKSCluster: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateSKSCluster: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-sks-cluster")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateSKSCluster: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateSKSCluster: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateSKSCluster: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type GetSKSClusterAuthorityCertResponse struct {
	Cacert string `json:"cacert,omitempty"`
}

type GetSKSClusterAuthorityCertAuthority string

const (
	GetSKSClusterAuthorityCertAuthorityControlPlane GetSKSClusterAuthorityCertAuthority = "control-plane"
	GetSKSClusterAuthorityCertAuthorityAggregation  GetSKSClusterAuthorityCertAuthority = "aggregation"
	GetSKSClusterAuthorityCertAuthorityKubelet      GetSKSClusterAuthorityCertAuthority = "kubelet"
)

// This operation returns the certificate for the given SKS cluster authority encoded in base64.
func (c Client) GetSKSClusterAuthorityCert(ctx context.Context, id UUID, authority GetSKSClusterAuthorityCertAuthority) (*GetSKSClusterAuthorityCertResponse, error) {
	path := fmt.Sprintf("/sks-cluster/%v/authority/%v/cert", id, authority)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetSKSClusterAuthorityCert: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetSKSClusterAuthorityCert: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetSKSClusterAuthorityCert: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-sks-cluster-authority-cert")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetSKSClusterAuthorityCert: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetSKSClusterAuthorityCert: http response: %w", err)
	}

	bodyresp := new(GetSKSClusterAuthorityCertResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetSKSClusterAuthorityCert: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type GenerateSKSKarpenterExoscaleNodeclassResponse struct {
	ExoscaleNodeclass string `json:"exoscale-nodeclass,omitempty"`
}

// Generate a Karpenter ExoscaleNodeClass manifest for an SKS cluster, including its default security group and feature flags if present
func (c Client) GenerateSKSKarpenterExoscaleNodeclass(ctx context.Context, id UUID) (*GenerateSKSKarpenterExoscaleNodeclassResponse, error) {
	path := fmt.Sprintf("/sks-cluster/%v/generate-karpenter-exoscale-nodeclass", id)

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GenerateSKSKarpenterExoscaleNodeclass: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GenerateSKSKarpenterExoscaleNodeclass: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GenerateSKSKarpenterExoscaleNodeclass: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "generate-sks-karpenter-exoscale-nodeclass")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GenerateSKSKarpenterExoscaleNodeclass: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GenerateSKSKarpenterExoscaleNodeclass: http response: %w", err)
	}

	bodyresp := new(GenerateSKSKarpenterExoscaleNodeclassResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GenerateSKSKarpenterExoscaleNodeclass: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type GenerateSKSKarpenterNodepoolResponse struct {
	Nodepool string `json:"nodepool,omitempty"`
}

// Generate a Karpenter NodePool manifest with minimal configuration for an SKS cluster
func (c Client) GenerateSKSKarpenterNodepool(ctx context.Context, id UUID) (*GenerateSKSKarpenterNodepoolResponse, error) {
	path := fmt.Sprintf("/sks-cluster/%v/generate-karpenter-nodepool", id)

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GenerateSKSKarpenterNodepool: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GenerateSKSKarpenterNodepool: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GenerateSKSKarpenterNodepool: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "generate-sks-karpenter-nodepool")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GenerateSKSKarpenterNodepool: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GenerateSKSKarpenterNodepool: http response: %w", err)
	}

	bodyresp := new(GenerateSKSKarpenterNodepoolResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GenerateSKSKarpenterNodepool: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type GetSKSClusterInspectionResponse map[string]any

// Helps troubleshoot common problems when deploying a kubernetes cluster. Inspections run every couple of minutes.
func (c Client) GetSKSClusterInspection(ctx context.Context, id UUID) (*GetSKSClusterInspectionResponse, error) {
	path := fmt.Sprintf("/sks-cluster/%v/inspection", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetSKSClusterInspection: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetSKSClusterInspection: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetSKSClusterInspection: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-sks-cluster-inspection")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetSKSClusterInspection: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetSKSClusterInspection: http response: %w", err)
	}

	bodyresp := new(GetSKSClusterInspectionResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetSKSClusterInspection: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type CreateSKSNodepoolRequestPublicIPAssignment string

const (
	CreateSKSNodepoolRequestPublicIPAssignmentInet4 CreateSKSNodepoolRequestPublicIPAssignment = "inet4"
	CreateSKSNodepoolRequestPublicIPAssignmentDual  CreateSKSNodepoolRequestPublicIPAssignment = "dual"
)

type CreateSKSNodepoolRequest struct {
	// Nodepool addons
	Addons []string `json:"addons,omitempty"`
	// Nodepool Anti-affinity Groups
	AntiAffinityGroups []AntiAffinityGroup `json:"anti-affinity-groups,omitempty"`
	// Deploy target reference
	DeployTarget *DeployTarget `json:"deploy-target,omitempty"`
	// Nodepool description
	Description string `json:"description,omitempty" validate:"omitempty,lte=255"`
	// Nodepool instances disk size in GiB
	DiskSize int64 `json:"disk-size" validate:"required,gte=20,lte=51200"`
	// Prefix to apply to instances names (default: pool), lowercase only
	InstancePrefix string `json:"instance-prefix,omitempty" validate:"omitempty,gte=1,lte=30"`
	// Instance type reference
	InstanceType *InstanceType `json:"instance-type" validate:"required"`
	// Kubelet image GC options
	KubeletImageGC *KubeletImageGC   `json:"kubelet-image-gc,omitempty"`
	Labels         SKSNodepoolLabels `json:"labels,omitempty"`
	// Nodepool name, lowercase only
	Name string `json:"name" validate:"required,gte=1,lte=255"`
	// Nvidia MIG Profiles enabled
	NvidiaMigProfiles *NvidiaMigProfiles `json:"nvidia-mig-profiles,omitempty"`
	// Nodepool Private Networks
	PrivateNetworks []PrivateNetwork `json:"private-networks,omitempty"`
	// Configures public IP assignment of the Instances with:
	// * both IPv4 and IPv6 (`dual`) addressing.
	// * both IPv4 and IPv6 (`dual`) addressing.
	PublicIPAssignment CreateSKSNodepoolRequestPublicIPAssignment `json:"public-ip-assignment,omitempty"`
	// Nodepool Security Groups
	SecurityGroups []SecurityGroup `json:"security-groups,omitempty"`
	// Number of instances
	Size   int64             `json:"size" validate:"required,gt=0"`
	Taints SKSNodepoolTaints `json:"taints,omitempty"`
}

// Create a new SKS Nodepool
func (c Client) CreateSKSNodepool(ctx context.Context, id UUID, req CreateSKSNodepoolRequest) (*Operation, error) {
	path := fmt.Sprintf("/sks-cluster/%v/nodepool", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateSKSNodepool: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateSKSNodepool: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateSKSNodepool: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateSKSNodepool: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-sks-nodepool")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateSKSNodepool: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateSKSNodepool: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateSKSNodepool: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Delete an SKS Nodepool
func (c Client) DeleteSKSNodepool(ctx context.Context, id UUID, sksNodepoolID UUID) (*Operation, error) {
	path := fmt.Sprintf("/sks-cluster/%v/nodepool/%v", id, sksNodepoolID)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteSKSNodepool: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteSKSNodepool: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteSKSNodepool: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-sks-nodepool")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteSKSNodepool: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteSKSNodepool: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteSKSNodepool: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Retrieve SKS Nodepool details
func (c Client) GetSKSNodepool(ctx context.Context, id UUID, sksNodepoolID UUID) (*SKSNodepool, error) {
	path := fmt.Sprintf("/sks-cluster/%v/nodepool/%v", id, sksNodepoolID)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetSKSNodepool: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetSKSNodepool: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetSKSNodepool: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-sks-nodepool")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetSKSNodepool: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetSKSNodepool: http response: %w", err)
	}

	bodyresp := new(SKSNodepool)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetSKSNodepool: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type UpdateSKSNodepoolRequestPublicIPAssignment string

const (
	UpdateSKSNodepoolRequestPublicIPAssignmentInet4 UpdateSKSNodepoolRequestPublicIPAssignment = "inet4"
	UpdateSKSNodepoolRequestPublicIPAssignmentDual  UpdateSKSNodepoolRequestPublicIPAssignment = "dual"
)

type UpdateSKSNodepoolRequest struct {
	// Nodepool Anti-affinity Groups
	AntiAffinityGroups []AntiAffinityGroup `json:"anti-affinity-groups,omitempty"`
	// Deploy target reference
	DeployTarget *DeployTarget `json:"deploy-target"`
	// Nodepool description
	Description string `json:"description,omitempty" validate:"omitempty,lte=255"`
	// Nodepool instances disk size in GiB
	DiskSize int64 `json:"disk-size,omitempty" validate:"omitempty,gte=20,lte=51200"`
	// Prefix to apply to managed instances names (default: pool), lowercase only
	InstancePrefix string `json:"instance-prefix,omitempty" validate:"omitempty,gte=1,lte=30"`
	// Instance type reference
	InstanceType *InstanceType `json:"instance-type,omitempty"`
	// Kubelet image GC options
	KubeletImageGC *KubeletImageGC   `json:"kubelet-image-gc,omitempty"`
	Labels         SKSNodepoolLabels `json:"labels,omitempty"`
	// Nodepool name, lowercase only
	Name string `json:"name,omitempty" validate:"omitempty,gte=1,lte=255"`
	// Nvidia MIG Profiles enabled
	NvidiaMigProfiles *NvidiaMigProfiles `json:"nvidia-mig-profiles"`
	// Nodepool Private Networks
	PrivateNetworks []PrivateNetwork `json:"private-networks,omitempty"`
	// Configures public IP assignment of the Instances with:
	// * both IPv4 and IPv6 (`dual`) addressing.
	// * both IPv4 and IPv6 (`dual`) addressing.
	PublicIPAssignment UpdateSKSNodepoolRequestPublicIPAssignment `json:"public-ip-assignment,omitempty"`
	// Nodepool Security Groups
	SecurityGroups []SecurityGroup   `json:"security-groups,omitempty"`
	Taints         SKSNodepoolTaints `json:"taints,omitempty"`
}

// Update an SKS Nodepool
func (c Client) UpdateSKSNodepool(ctx context.Context, id UUID, sksNodepoolID UUID, req UpdateSKSNodepoolRequest) (*Operation, error) {
	path := fmt.Sprintf("/sks-cluster/%v/nodepool/%v", id, sksNodepoolID)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateSKSNodepool: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateSKSNodepool: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateSKSNodepool: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateSKSNodepool: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-sks-nodepool")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateSKSNodepool: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateSKSNodepool: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateSKSNodepool: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type EvictSKSNodepoolMembersRequest struct {
	Instances []UUID `json:"instances,omitempty"`
}

// This operation evicts the specified Compute instances member from the Nodepool, shrinking it to `&lt;current nodepool size&gt; - &lt;# evicted members&gt;`.
func (c Client) EvictSKSNodepoolMembers(ctx context.Context, id UUID, sksNodepoolID UUID, req EvictSKSNodepoolMembersRequest) (*Operation, error) {
	path := fmt.Sprintf("/sks-cluster/%v/nodepool/%v:evict", id, sksNodepoolID)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("EvictSKSNodepoolMembers: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("EvictSKSNodepoolMembers: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("EvictSKSNodepoolMembers: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("EvictSKSNodepoolMembers: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "evict-sks-nodepool-members")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("EvictSKSNodepoolMembers: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("EvictSKSNodepoolMembers: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("EvictSKSNodepoolMembers: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ScaleSKSNodepoolRequest struct {
	// Number of instances
	Size int64 `json:"size" validate:"required,gte=0"`
}

// Scale a SKS Nodepool
func (c Client) ScaleSKSNodepool(ctx context.Context, id UUID, sksNodepoolID UUID, req ScaleSKSNodepoolRequest) (*Operation, error) {
	path := fmt.Sprintf("/sks-cluster/%v/nodepool/%v:scale", id, sksNodepoolID)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("ScaleSKSNodepool: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("ScaleSKSNodepool: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ScaleSKSNodepool: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ScaleSKSNodepool: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "scale-sks-nodepool")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ScaleSKSNodepool: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ScaleSKSNodepool: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ScaleSKSNodepool: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Rotate Exoscale CCM credentials
func (c Client) RotateSKSCcmCredentials(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/sks-cluster/%v/rotate-ccm-credentials", id)

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("RotateSKSCcmCredentials: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("RotateSKSCcmCredentials: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("RotateSKSCcmCredentials: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "rotate-sks-ccm-credentials")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("RotateSKSCcmCredentials: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("RotateSKSCcmCredentials: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("RotateSKSCcmCredentials: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Rotate Exoscale CSI credentials
func (c Client) RotateSKSCsiCredentials(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/sks-cluster/%v/rotate-csi-credentials", id)

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("RotateSKSCsiCredentials: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("RotateSKSCsiCredentials: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("RotateSKSCsiCredentials: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "rotate-sks-csi-credentials")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("RotateSKSCsiCredentials: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("RotateSKSCsiCredentials: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("RotateSKSCsiCredentials: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Rotate Exoscale Karpenter credentials
func (c Client) RotateSKSKarpenterCredentials(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/sks-cluster/%v/rotate-karpenter-credentials", id)

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("RotateSKSKarpenterCredentials: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("RotateSKSKarpenterCredentials: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("RotateSKSKarpenterCredentials: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "rotate-sks-karpenter-credentials")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("RotateSKSKarpenterCredentials: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("RotateSKSKarpenterCredentials: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("RotateSKSKarpenterCredentials: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Rotate operators certificate authority
func (c Client) RotateSKSOperatorsCA(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/sks-cluster/%v/rotate-operators-ca", id)

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("RotateSKSOperatorsCA: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("RotateSKSOperatorsCA: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("RotateSKSOperatorsCA: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "rotate-sks-operators-ca")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("RotateSKSOperatorsCA: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("RotateSKSOperatorsCA: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("RotateSKSOperatorsCA: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type UpgradeSKSClusterRequest struct {
	// Control plane Kubernetes version
	Version string `json:"version" validate:"required"`
}

// Upgrade an SKS cluster
func (c Client) UpgradeSKSCluster(ctx context.Context, id UUID, req UpgradeSKSClusterRequest) (*Operation, error) {
	path := fmt.Sprintf("/sks-cluster/%v/upgrade", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpgradeSKSCluster: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpgradeSKSCluster: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpgradeSKSCluster: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpgradeSKSCluster: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "upgrade-sks-cluster")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpgradeSKSCluster: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpgradeSKSCluster: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpgradeSKSCluster: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Upgrade a SKS cluster to pro
func (c Client) UpgradeSKSClusterServiceLevel(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/sks-cluster/%v/upgrade-service-level", id)

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("UpgradeSKSClusterServiceLevel: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpgradeSKSClusterServiceLevel: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpgradeSKSClusterServiceLevel: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "upgrade-sks-cluster-service-level")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpgradeSKSClusterServiceLevel: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpgradeSKSClusterServiceLevel: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpgradeSKSClusterServiceLevel: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type GetActiveNodepoolTemplateResponse struct {
	ActiveTemplate UUID `json:"active-template,omitempty"`
}

type GetActiveNodepoolTemplateVariant string

const (
	GetActiveNodepoolTemplateVariantStandard GetActiveNodepoolTemplateVariant = "standard"
	GetActiveNodepoolTemplateVariantNvidia   GetActiveNodepoolTemplateVariant = "nvidia"
)

// Get the active template for a given kube version and variant (standard | nvidia)
func (c Client) GetActiveNodepoolTemplate(ctx context.Context, kubeVersion string, variant GetActiveNodepoolTemplateVariant) (*GetActiveNodepoolTemplateResponse, error) {
	path := fmt.Sprintf("/sks-template/%v/%v", kubeVersion, variant)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetActiveNodepoolTemplate: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetActiveNodepoolTemplate: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetActiveNodepoolTemplate: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-active-nodepool-template")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetActiveNodepoolTemplate: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetActiveNodepoolTemplate: http response: %w", err)
	}

	bodyresp := new(GetActiveNodepoolTemplateResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetActiveNodepoolTemplate: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ListSnapshotsResponse struct {
	Snapshots []Snapshot `json:"snapshots,omitempty"`
}

// FindSnapshot attempts to find an Snapshot by nameOrID.
func (l ListSnapshotsResponse) FindSnapshot(nameOrID string) (Snapshot, error) {
	var result []Snapshot
	for i, elem := range l.Snapshots {
		if string(elem.Name) == nameOrID || string(elem.ID) == nameOrID {
			result = append(result, l.Snapshots[i])
		}
	}
	if len(result) == 1 {
		return result[0], nil
	}

	if len(result) > 1 {
		return Snapshot{}, fmt.Errorf("%q too many found in ListSnapshotsResponse: %w", nameOrID, ErrConflict)
	}

	return Snapshot{}, fmt.Errorf("%q not found in ListSnapshotsResponse: %w", nameOrID, ErrNotFound)
}

// List Snapshots
func (c Client) ListSnapshots(ctx context.Context) (*ListSnapshotsResponse, error) {
	path := "/snapshot"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListSnapshots: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListSnapshots: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListSnapshots: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-snapshots")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListSnapshots: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListSnapshots: http response: %w", err)
	}

	bodyresp := new(ListSnapshotsResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListSnapshots: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Delete a Snapshot
func (c Client) DeleteSnapshot(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/snapshot/%v", id)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteSnapshot: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteSnapshot: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteSnapshot: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-snapshot")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteSnapshot: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteSnapshot: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteSnapshot: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Retrieve Snapshot details
func (c Client) GetSnapshot(ctx context.Context, id UUID) (*Snapshot, error) {
	path := fmt.Sprintf("/snapshot/%v", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetSnapshot: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetSnapshot: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetSnapshot: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-snapshot")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetSnapshot: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetSnapshot: http response: %w", err)
	}

	bodyresp := new(Snapshot)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetSnapshot: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Export a Snapshot
func (c Client) ExportSnapshot(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/snapshot/%v:export", id)

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ExportSnapshot: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ExportSnapshot: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ExportSnapshot: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "export-snapshot")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ExportSnapshot: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ExportSnapshot: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ExportSnapshot: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type PromoteSnapshotToTemplateRequest struct {
	// Template default user
	DefaultUser string `json:"default-user,omitempty" validate:"omitempty,gte=1,lte=255"`
	// Template description
	Description string `json:"description,omitempty" validate:"omitempty,lte=4096"`
	// Template name
	Name string `json:"name" validate:"required,gte=1,lte=255"`
	// Enable password-based login in the template
	PasswordEnabled *bool `json:"password-enabled,omitempty"`
	// Enable SSH key-based login in the template
	SSHKeyEnabled *bool `json:"ssh-key-enabled,omitempty"`
}

// Promote a Snapshot to a Template
func (c Client) PromoteSnapshotToTemplate(ctx context.Context, id UUID, req PromoteSnapshotToTemplateRequest) (*Operation, error) {
	path := fmt.Sprintf("/snapshot/%v:promote", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("PromoteSnapshotToTemplate: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("PromoteSnapshotToTemplate: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("PromoteSnapshotToTemplate: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("PromoteSnapshotToTemplate: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "promote-snapshot-to-template")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("PromoteSnapshotToTemplate: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("PromoteSnapshotToTemplate: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("PromoteSnapshotToTemplate: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ListSOSBucketsUsageResponse struct {
	SOSBucketsUsage []SOSBucketUsage `json:"sos-buckets-usage,omitempty"`
}

// FindSOSBucketUsage attempts to find an SOSBucketUsage by name.
func (l ListSOSBucketsUsageResponse) FindSOSBucketUsage(name string) (SOSBucketUsage, error) {
	var result []SOSBucketUsage
	for i, elem := range l.SOSBucketsUsage {
		if string(elem.Name) == name {
			result = append(result, l.SOSBucketsUsage[i])
		}
	}
	if len(result) == 1 {
		return result[0], nil
	}

	if len(result) > 1 {
		return SOSBucketUsage{}, fmt.Errorf("%q too many found in ListSOSBucketsUsageResponse: %w", name, ErrConflict)
	}

	return SOSBucketUsage{}, fmt.Errorf("%q not found in ListSOSBucketsUsageResponse: %w", name, ErrNotFound)
}

// List SOS Buckets Usage
func (c Client) ListSOSBucketsUsage(ctx context.Context) (*ListSOSBucketsUsageResponse, error) {
	path := "/sos-buckets-usage"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListSOSBucketsUsage: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListSOSBucketsUsage: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListSOSBucketsUsage: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-sos-buckets-usage")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListSOSBucketsUsage: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListSOSBucketsUsage: http response: %w", err)
	}

	bodyresp := new(ListSOSBucketsUsageResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListSOSBucketsUsage: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type GetSOSPresignedURLResponse struct {
	URL string `json:"url,omitempty"`
}

type GetSOSPresignedURLOpt func(url.Values)

func GetSOSPresignedURLWithKey(key string) GetSOSPresignedURLOpt {
	return func(q url.Values) {
		q.Add("key", fmt.Sprint(key))
	}
}

// Generates Presigned Download URL for SOS object
func (c Client) GetSOSPresignedURL(ctx context.Context, bucket string, opts ...GetSOSPresignedURLOpt) (*GetSOSPresignedURLResponse, error) {
	path := fmt.Sprintf("/sos/%v/presigned-url", bucket)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetSOSPresignedURL: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if len(opts) > 0 {
		q := request.URL.Query()
		for _, opt := range opts {
			opt(q)
		}
		request.URL.RawQuery = q.Encode()
	}

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetSOSPresignedURL: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetSOSPresignedURL: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-sos-presigned-url")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetSOSPresignedURL: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetSOSPresignedURL: http response: %w", err)
	}

	bodyresp := new(GetSOSPresignedURLResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetSOSPresignedURL: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ListSSHKeysResponse struct {
	SSHKeys []SSHKey `json:"ssh-keys,omitempty"`
}

// FindSSHKey attempts to find an SSHKey by nameOrFingerprint.
func (l ListSSHKeysResponse) FindSSHKey(nameOrFingerprint string) (SSHKey, error) {
	var result []SSHKey
	for i, elem := range l.SSHKeys {
		if string(elem.Name) == nameOrFingerprint || string(elem.Fingerprint) == nameOrFingerprint {
			result = append(result, l.SSHKeys[i])
		}
	}
	if len(result) == 1 {
		return result[0], nil
	}

	if len(result) > 1 {
		return SSHKey{}, fmt.Errorf("%q too many found in ListSSHKeysResponse: %w", nameOrFingerprint, ErrConflict)
	}

	return SSHKey{}, fmt.Errorf("%q not found in ListSSHKeysResponse: %w", nameOrFingerprint, ErrNotFound)
}

// List SSH keys
func (c Client) ListSSHKeys(ctx context.Context) (*ListSSHKeysResponse, error) {
	path := "/ssh-key"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListSSHKeys: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListSSHKeys: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListSSHKeys: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-ssh-keys")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListSSHKeys: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListSSHKeys: http response: %w", err)
	}

	bodyresp := new(ListSSHKeysResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListSSHKeys: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type RegisterSSHKeyRequest struct {
	// SSH key name
	Name string `json:"name" validate:"required"`
	// Public key value
	PublicKey string `json:"public-key" validate:"required"`
}

// Import SSH key
func (c Client) RegisterSSHKey(ctx context.Context, req RegisterSSHKeyRequest) (*Operation, error) {
	path := "/ssh-key"

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("RegisterSSHKey: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("RegisterSSHKey: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("RegisterSSHKey: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("RegisterSSHKey: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "register-ssh-key")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("RegisterSSHKey: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("RegisterSSHKey: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("RegisterSSHKey: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Delete a SSH key
func (c Client) DeleteSSHKey(ctx context.Context, name string) (*Operation, error) {
	path := fmt.Sprintf("/ssh-key/%v", name)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteSSHKey: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteSSHKey: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteSSHKey: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-ssh-key")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteSSHKey: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteSSHKey: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteSSHKey: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Retrieve SSH key details
func (c Client) GetSSHKey(ctx context.Context, name string) (*SSHKey, error) {
	path := fmt.Sprintf("/ssh-key/%v", name)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetSSHKey: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetSSHKey: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetSSHKey: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-ssh-key")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetSSHKey: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetSSHKey: http response: %w", err)
	}

	bodyresp := new(SSHKey)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetSSHKey: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ListTemplatesResponse struct {
	Templates []Template `json:"templates,omitempty"`
}

// FindTemplate attempts to find an Template by nameOrID.
func (l ListTemplatesResponse) FindTemplate(nameOrID string) (Template, error) {
	var result []Template
	for i, elem := range l.Templates {
		if string(elem.Name) == nameOrID || string(elem.ID) == nameOrID {
			result = append(result, l.Templates[i])
		}
	}
	if len(result) == 1 {
		return result[0], nil
	}

	if len(result) > 1 {
		return Template{}, fmt.Errorf("%q too many found in ListTemplatesResponse: %w", nameOrID, ErrConflict)
	}

	return Template{}, fmt.Errorf("%q not found in ListTemplatesResponse: %w", nameOrID, ErrNotFound)
}

type ListTemplatesVisibility string

const (
	ListTemplatesVisibilityPrivate ListTemplatesVisibility = "private"
	ListTemplatesVisibilityPublic  ListTemplatesVisibility = "public"
)

type ListTemplatesOpt func(url.Values)

func ListTemplatesWithVisibility(visibility ListTemplatesVisibility) ListTemplatesOpt {
	return func(q url.Values) {
		q.Add("visibility", fmt.Sprint(visibility))
	}
}

func ListTemplatesWithFamily(family string) ListTemplatesOpt {
	return func(q url.Values) {
		q.Add("family", fmt.Sprint(family))
	}
}

// List Templates
func (c Client) ListTemplates(ctx context.Context, opts ...ListTemplatesOpt) (*ListTemplatesResponse, error) {
	path := "/template"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListTemplates: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if len(opts) > 0 {
		q := request.URL.Query()
		for _, opt := range opts {
			opt(q)
		}
		request.URL.RawQuery = q.Encode()
	}

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListTemplates: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListTemplates: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-templates")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListTemplates: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListTemplates: http response: %w", err)
	}

	bodyresp := new(ListTemplatesResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListTemplates: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type RegisterTemplateRequestBootMode string

const (
	RegisterTemplateRequestBootModeLegacy RegisterTemplateRequestBootMode = "legacy"
	RegisterTemplateRequestBootModeUefi   RegisterTemplateRequestBootMode = "uefi"
)

type RegisterTemplateRequest struct {
	// Template with support for Application Consistent Snapshots
	ApplicationConsistentSnapshotEnabled *bool `json:"application-consistent-snapshot-enabled,omitempty"`
	// Boot mode (default: legacy)
	BootMode RegisterTemplateRequestBootMode `json:"boot-mode,omitempty"`
	// Template build
	Build string `json:"build,omitempty" validate:"omitempty,gte=1,lte=255"`
	// Template MD5 checksum
	Checksum string `json:"checksum" validate:"required,gte=1"`
	// Template default user
	DefaultUser string `json:"default-user,omitempty" validate:"omitempty,gte=1,lte=255"`
	// Template description
	Description string `json:"description,omitempty" validate:"omitempty,lte=255"`
	// Template maintainer
	Maintainer string `json:"maintainer,omitempty" validate:"omitempty,gte=1,lte=255"`
	// Template name
	Name string `json:"name" validate:"required,gte=1,lte=255"`
	// Enable password-based login
	PasswordEnabled *bool `json:"password-enabled" validate:"required"`
	// Template size
	Size int64 `json:"size,omitempty" validate:"omitempty,gt=0"`
	// Enable SSH key-based login
	SSHKeyEnabled *bool `json:"ssh-key-enabled" validate:"required"`
	// Template source URL
	URL string `json:"url" validate:"required,gte=1"`
	// Template version
	Version string `json:"version,omitempty" validate:"omitempty,gte=1,lte=255"`
}

// Register a Template
func (c Client) RegisterTemplate(ctx context.Context, req RegisterTemplateRequest) (*Operation, error) {
	path := "/template"

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("RegisterTemplate: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("RegisterTemplate: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("RegisterTemplate: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("RegisterTemplate: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "register-template")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("RegisterTemplate: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("RegisterTemplate: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("RegisterTemplate: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Delete a Template
func (c Client) DeleteTemplate(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/template/%v", id)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteTemplate: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteTemplate: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteTemplate: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-template")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteTemplate: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteTemplate: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteTemplate: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Retrieve Template details
func (c Client) GetTemplate(ctx context.Context, id UUID) (*Template, error) {
	path := fmt.Sprintf("/template/%v", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetTemplate: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetTemplate: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetTemplate: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-template")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetTemplate: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetTemplate: http response: %w", err)
	}

	bodyresp := new(Template)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetTemplate: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type CopyTemplateRequest struct {
	// Zone
	TargetZone *Zone `json:"target-zone" validate:"required"`
}

// Copy a Template from a zone to another
func (c Client) CopyTemplate(ctx context.Context, id UUID, req CopyTemplateRequest) (*Operation, error) {
	path := fmt.Sprintf("/template/%v", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CopyTemplate: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CopyTemplate: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CopyTemplate: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CopyTemplate: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "copy-template")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CopyTemplate: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CopyTemplate: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CopyTemplate: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type UpdateTemplateRequest struct {
	// Template Description
	Description string `json:"description,omitempty" validate:"omitempty,lte=255"`
	// Template name
	Name string `json:"name,omitempty" validate:"omitempty,gte=1,lte=255"`
}

// Update template attributes
func (c Client) UpdateTemplate(ctx context.Context, id UUID, req UpdateTemplateRequest) (*Operation, error) {
	path := fmt.Sprintf("/template/%v", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateTemplate: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateTemplate: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateTemplate: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateTemplate: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-template")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateTemplate: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateTemplate: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateTemplate: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// Usage
type GetUsageReportResponseUsage struct {
	// Description
	Description string `json:"description,omitempty"`
	// Period Start Date
	From string `json:"from,omitempty"`
	// Product
	Product string `json:"product,omitempty"`
	// Quantity
	Quantity string `json:"quantity,omitempty"`
	// Period End Date
	To string `json:"to,omitempty"`
	// Unit
	Unit string `json:"unit,omitempty"`
	// Variable
	Variable string `json:"variable,omitempty"`
}

type GetUsageReportResponse struct {
	Usage []GetUsageReportResponseUsage `json:"usage,omitempty"`
}

type GetUsageReportOpt func(url.Values)

func GetUsageReportWithPeriod(period string) GetUsageReportOpt {
	return func(q url.Values) {
		q.Add("period", fmt.Sprint(period))
	}
}

// Returns aggregated usage reports for an organization
func (c Client) GetUsageReport(ctx context.Context, opts ...GetUsageReportOpt) (*GetUsageReportResponse, error) {
	path := "/usage-report"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetUsageReport: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if len(opts) > 0 {
		q := request.URL.Query()
		for _, opt := range opts {
			opt(q)
		}
		request.URL.RawQuery = q.Encode()
	}

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetUsageReport: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetUsageReport: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-usage-report")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetUsageReport: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetUsageReport: http response: %w", err)
	}

	bodyresp := new(GetUsageReportResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetUsageReport: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ListUsersResponse struct {
	Users []User `json:"users,omitempty"`
}

// FindUser attempts to find an User by id.
func (l ListUsersResponse) FindUser(id string) (User, error) {
	var result []User
	for i, elem := range l.Users {
		if string(elem.ID) == id {
			result = append(result, l.Users[i])
		}
	}
	if len(result) == 1 {
		return result[0], nil
	}

	if len(result) > 1 {
		return User{}, fmt.Errorf("%q too many found in ListUsersResponse: %w", id, ErrConflict)
	}

	return User{}, fmt.Errorf("%q not found in ListUsersResponse: %w", id, ErrNotFound)
}

func (c Client) ListUsers(ctx context.Context) (*ListUsersResponse, error) {
	path := "/user"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListUsers: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListUsers: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListUsers: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-users")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListUsers: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListUsers: http response: %w", err)
	}

	bodyresp := new(ListUsersResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListUsers: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type CreateUserRequest struct {
	// User Email
	Email string `json:"email" validate:"required"`
	// IAM Role
	Role *IAMRole `json:"role,omitempty"`
}

func (c Client) CreateUser(ctx context.Context, req CreateUserRequest) (*Operation, error) {
	path := "/user"

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateUser: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateUser: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateUser: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateUser: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-user")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateUser: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateUser: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateUser: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

func (c Client) DeleteUser(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/user/%v", id)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteUser: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteUser: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteUser: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-user")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteUser: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteUser: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteUser: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type UpdateUserRoleRequest struct {
	// IAM Role
	Role *IAMRole `json:"role,omitempty"`
}

func (c Client) UpdateUserRole(ctx context.Context, id UUID, req UpdateUserRoleRequest) (*Operation, error) {
	path := fmt.Sprintf("/user/%v", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateUserRole: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateUserRole: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateUserRole: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateUserRole: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-user-role")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateUserRole: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateUserRole: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateUserRole: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ListVpcsResponse struct {
	Vpcs []ListVpcEntry `json:"vpcs,omitempty"`
}

// FindListVpcEntry attempts to find an ListVpcEntry by nameOrID.
func (l ListVpcsResponse) FindListVpcEntry(nameOrID string) (ListVpcEntry, error) {
	var result []ListVpcEntry
	for i, elem := range l.Vpcs {
		if string(elem.Name) == nameOrID || string(elem.ID) == nameOrID {
			result = append(result, l.Vpcs[i])
		}
	}
	if len(result) == 1 {
		return result[0], nil
	}

	if len(result) > 1 {
		return ListVpcEntry{}, fmt.Errorf("%q too many found in ListVpcsResponse: %w", nameOrID, ErrConflict)
	}

	return ListVpcEntry{}, fmt.Errorf("%q not found in ListVpcsResponse: %w", nameOrID, ErrNotFound)
}

// [BETA] List VPCs
func (c Client) ListVpcs(ctx context.Context) (*ListVpcsResponse, error) {
	path := "/vpc"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListVpcs: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListVpcs: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListVpcs: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-vpcs")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListVpcs: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListVpcs: http response: %w", err)
	}

	bodyresp := new(ListVpcsResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListVpcs: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type CreateVpcRequest struct {
	// VPC description
	Description string `json:"description,omitempty" validate:"omitempty,lte=4096"`
	Labels      Labels `json:"labels,omitempty"`
	// VPC name
	Name string `json:"name" validate:"required,gte=1,lte=255"`
}

// [BETA] Create a VPC
func (c Client) CreateVpc(ctx context.Context, req CreateVpcRequest) (*Operation, error) {
	path := "/vpc"

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateVpc: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateVpc: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateVpc: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateVpc: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-vpc")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateVpc: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateVpc: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateVpc: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// [BETA] Delete a VPC
func (c Client) DeleteVpc(ctx context.Context, id UUID) (*Empty, error) {
	path := fmt.Sprintf("/vpc/%v", id)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteVpc: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteVpc: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteVpc: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-vpc")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteVpc: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteVpc: http response: %w", err)
	}

	bodyresp := new(Empty)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteVpc: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// [BETA] Retrieve VPC details
func (c Client) GetVpc(ctx context.Context, id UUID) (*Vpc, error) {
	path := fmt.Sprintf("/vpc/%v", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetVpc: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetVpc: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetVpc: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-vpc")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetVpc: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetVpc: http response: %w", err)
	}

	bodyresp := new(Vpc)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetVpc: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type UpdateVpcRequest struct {
	// VPC description
	Description *string `json:"description,omitempty" validate:"omitempty,lte=4096"`
	Labels      Labels  `json:"labels"`
	// VPC name
	Name *string `json:"name,omitempty" validate:"omitempty,gte=1,lte=255"`
}

// [BETA] Update a VPC
func (c Client) UpdateVpc(ctx context.Context, id UUID, req UpdateVpcRequest) (*Vpc, error) {
	path := fmt.Sprintf("/vpc/%v", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateVpc: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateVpc: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateVpc: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateVpc: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-vpc")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateVpc: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateVpc: http response: %w", err)
	}

	bodyresp := new(Vpc)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateVpc: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ListVpcRoutesResponse struct {
	Routes []ListRouteEntry `json:"routes,omitempty"`
}

// FindListRouteEntry attempts to find an ListRouteEntry by id.
func (l ListVpcRoutesResponse) FindListRouteEntry(id string) (ListRouteEntry, error) {
	var result []ListRouteEntry
	for i, elem := range l.Routes {
		if string(elem.ID) == id {
			result = append(result, l.Routes[i])
		}
	}
	if len(result) == 1 {
		return result[0], nil
	}

	if len(result) > 1 {
		return ListRouteEntry{}, fmt.Errorf("%q too many found in ListVpcRoutesResponse: %w", id, ErrConflict)
	}

	return ListRouteEntry{}, fmt.Errorf("%q not found in ListVpcRoutesResponse: %w", id, ErrNotFound)
}

// [BETA] List VPC routes
func (c Client) ListVpcRoutes(ctx context.Context, vpcID UUID) (*ListVpcRoutesResponse, error) {
	path := fmt.Sprintf("/vpc/%v/route", vpcID)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListVpcRoutes: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListVpcRoutes: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListVpcRoutes: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-vpc-routes")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListVpcRoutes: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListVpcRoutes: http response: %w", err)
	}

	bodyresp := new(ListVpcRoutesResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListVpcRoutes: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ListSubnetsResponse struct {
	Subnets []ListSubnetEntry `json:"subnets,omitempty"`
}

// FindListSubnetEntry attempts to find an ListSubnetEntry by nameOrID.
func (l ListSubnetsResponse) FindListSubnetEntry(nameOrID string) (ListSubnetEntry, error) {
	var result []ListSubnetEntry
	for i, elem := range l.Subnets {
		if string(elem.Name) == nameOrID || string(elem.ID) == nameOrID {
			result = append(result, l.Subnets[i])
		}
	}
	if len(result) == 1 {
		return result[0], nil
	}

	if len(result) > 1 {
		return ListSubnetEntry{}, fmt.Errorf("%q too many found in ListSubnetsResponse: %w", nameOrID, ErrConflict)
	}

	return ListSubnetEntry{}, fmt.Errorf("%q not found in ListSubnetsResponse: %w", nameOrID, ErrNotFound)
}

// [BETA] List Subnets
func (c Client) ListSubnets(ctx context.Context, vpcID UUID) (*ListSubnetsResponse, error) {
	path := fmt.Sprintf("/vpc/%v/subnet", vpcID)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListSubnets: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListSubnets: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListSubnets: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-subnets")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListSubnets: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListSubnets: http response: %w", err)
	}

	bodyresp := new(ListSubnetsResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListSubnets: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type CreateSubnetRequestAddressSpace string

const (
	CreateSubnetRequestAddressSpacePrivate CreateSubnetRequestAddressSpace = "private"
)

type CreateSubnetRequestAddressfamily string

const (
	CreateSubnetRequestAddressfamilyInet4 CreateSubnetRequestAddressfamily = "inet4"
)

type CreateSubnetRequest struct {
	// Subnet address space
	AddressSpace CreateSubnetRequestAddressSpace `json:"address-space" validate:"required"`
	// Subnet address family
	Addressfamily CreateSubnetRequestAddressfamily `json:"addressfamily" validate:"required"`
	// Subnet description
	Description string `json:"description,omitempty" validate:"omitempty,lte=4096"`
	// Subnet ipv4 CIDR
	Ipv4Block string `json:"ipv4-block,omitempty"`
	Labels    Labels `json:"labels,omitempty"`
	// Subnet name
	Name string `json:"name" validate:"required,gte=1,lte=255"`
}

// [BETA] Create a Subnet
func (c Client) CreateSubnet(ctx context.Context, vpcID UUID, req CreateSubnetRequest) (*Operation, error) {
	path := fmt.Sprintf("/vpc/%v/subnet", vpcID)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateSubnet: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateSubnet: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateSubnet: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateSubnet: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-subnet")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateSubnet: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateSubnet: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateSubnet: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// [BETA] Delete a Subnet
func (c Client) DeleteSubnet(ctx context.Context, vpcID UUID, id UUID) (*Empty, error) {
	path := fmt.Sprintf("/vpc/%v/subnet/%v", vpcID, id)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteSubnet: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteSubnet: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteSubnet: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-subnet")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteSubnet: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteSubnet: http response: %w", err)
	}

	bodyresp := new(Empty)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteSubnet: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// [BETA] Retrieve Subnet details
func (c Client) GetSubnet(ctx context.Context, vpcID UUID, id UUID) (*Subnet, error) {
	path := fmt.Sprintf("/vpc/%v/subnet/%v", vpcID, id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetSubnet: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetSubnet: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetSubnet: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-subnet")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetSubnet: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetSubnet: http response: %w", err)
	}

	bodyresp := new(Subnet)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetSubnet: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type UpdateSubnetRequest struct {
	// Subnet description
	Description *string `json:"description,omitempty" validate:"omitempty,lte=4096"`
	// Subnet CIDR
	Ipv4Block *string `json:"ipv4-block,omitempty"`
	Labels    Labels  `json:"labels"`
	// Subnet name
	Name *string `json:"name,omitempty" validate:"omitempty,gte=1,lte=255"`
}

// [BETA] Update a Subnet
func (c Client) UpdateSubnet(ctx context.Context, vpcID UUID, id UUID, req UpdateSubnetRequest) (*Subnet, error) {
	path := fmt.Sprintf("/vpc/%v/subnet/%v", vpcID, id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateSubnet: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateSubnet: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateSubnet: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateSubnet: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-subnet")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateSubnet: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateSubnet: http response: %w", err)
	}

	bodyresp := new(Subnet)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateSubnet: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type AttachInstanceToSubnetRequest struct {
	// Target Instance
	Instance *InstanceRef `json:"instance" validate:"required"`
	// Instance IPv4
	Ipv4 net.IP `json:"ipv4,omitempty"`
}

// [BETA] Attach a Compute instance to a Subnet
func (c Client) AttachInstanceToSubnet(ctx context.Context, vpcID UUID, subnetID UUID, req AttachInstanceToSubnetRequest) (*Operation, error) {
	path := fmt.Sprintf("/vpc/%v/subnet/%v/attach", vpcID, subnetID)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("AttachInstanceToSubnet: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("AttachInstanceToSubnet: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("AttachInstanceToSubnet: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("AttachInstanceToSubnet: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "attach-instance-to-subnet")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("AttachInstanceToSubnet: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("AttachInstanceToSubnet: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("AttachInstanceToSubnet: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type DetachInstanceFromSubnetRequest struct {
	// Target Instance
	Instance *InstanceRef `json:"instance" validate:"required"`
}

// [BETA] Detach a Compute instance from a Subnet
func (c Client) DetachInstanceFromSubnet(ctx context.Context, vpcID UUID, subnetID UUID, req DetachInstanceFromSubnetRequest) (*Operation, error) {
	path := fmt.Sprintf("/vpc/%v/subnet/%v/detach", vpcID, subnetID)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("DetachInstanceFromSubnet: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("DetachInstanceFromSubnet: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DetachInstanceFromSubnet: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DetachInstanceFromSubnet: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "detach-instance-from-subnet")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DetachInstanceFromSubnet: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DetachInstanceFromSubnet: http response: %w", err)
	}

	bodyresp := new(Operation)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DetachInstanceFromSubnet: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ListRoutesResponse struct {
	Routes []ListRouteEntry `json:"routes,omitempty"`
}

// FindListRouteEntry attempts to find an ListRouteEntry by id.
func (l ListRoutesResponse) FindListRouteEntry(id string) (ListRouteEntry, error) {
	var result []ListRouteEntry
	for i, elem := range l.Routes {
		if string(elem.ID) == id {
			result = append(result, l.Routes[i])
		}
	}
	if len(result) == 1 {
		return result[0], nil
	}

	if len(result) > 1 {
		return ListRouteEntry{}, fmt.Errorf("%q too many found in ListRoutesResponse: %w", id, ErrConflict)
	}

	return ListRouteEntry{}, fmt.Errorf("%q not found in ListRoutesResponse: %w", id, ErrNotFound)
}

// [BETA] List Subnet routes
func (c Client) ListRoutes(ctx context.Context, vpcID UUID, subnetID UUID) (*ListRoutesResponse, error) {
	path := fmt.Sprintf("/vpc/%v/subnet/%v/route", vpcID, subnetID)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListRoutes: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListRoutes: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListRoutes: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-routes")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListRoutes: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListRoutes: http response: %w", err)
	}

	bodyresp := new(ListRoutesResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListRoutes: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type CreateRouteRequest struct {
	// Route description
	Description string `json:"description,omitempty" validate:"omitempty,lte=4096"`
	// Route destination CIDR
	Destination string `json:"destination" validate:"required"`
	// Route target
	Target string `json:"target" validate:"required"`
}

// [BETA] Create a route
func (c Client) CreateRoute(ctx context.Context, vpcID UUID, subnetID UUID, req CreateRouteRequest) (*Route, error) {
	path := fmt.Sprintf("/vpc/%v/subnet/%v/route", vpcID, subnetID)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateRoute: prepare JSON body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateRoute: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateRoute: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateRoute: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-route")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateRoute: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateRoute: http response: %w", err)
	}

	bodyresp := new(Route)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateRoute: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

// [BETA] Delete a route
func (c Client) DeleteRoute(ctx context.Context, vpcID UUID, subnetID UUID, id UUID) (*Empty, error) {
	path := fmt.Sprintf("/vpc/%v/subnet/%v/route/%v", vpcID, subnetID, id)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteRoute: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteRoute: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteRoute: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-route")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteRoute: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteRoute: http response: %w", err)
	}

	bodyresp := new(Empty)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteRoute: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}

type ListZonesResponse struct {
	Zones []Zone `json:"zones,omitempty"`
}

// FindZone attempts to find an Zone by nameOrAPIEndpoint.
func (l ListZonesResponse) FindZone(nameOrAPIEndpoint string) (Zone, error) {
	var result []Zone
	for i, elem := range l.Zones {
		if string(elem.Name) == nameOrAPIEndpoint || string(elem.APIEndpoint) == nameOrAPIEndpoint {
			result = append(result, l.Zones[i])
		}
	}
	if len(result) == 1 {
		return result[0], nil
	}

	if len(result) > 1 {
		return Zone{}, fmt.Errorf("%q too many found in ListZonesResponse: %w", nameOrAPIEndpoint, ErrConflict)
	}

	return Zone{}, fmt.Errorf("%q not found in ListZonesResponse: %w", nameOrAPIEndpoint, ErrNotFound)
}

// List Zones
func (c Client) ListZones(ctx context.Context) (*ListZonesResponse, error) {
	path := "/zone"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListZones: new request: %w", err)
	}

	request.Header.Add("User-Agent", c.getUserAgent())

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListZones: execute request editors: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-zones")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListZones: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListZones: http response: %w", err)
	}

	bodyresp := new(ListZonesResponse)
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListZones: prepare JSON response: %w", err)
	}

	return bodyresp, nil
}
