// This file was automatically generated. DO NOT EDIT.
// If you have any remark or suggestion do not hesitate to open an issue.

// Package key_manager provides methods and message types of the key_manager v1alpha1 API.
package key_manager

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net"
	"net/http"
	"net/url"
	"strings"
	"text/template"
	"time"

	"github.com/scaleway/scaleway-sdk-go/errors"
	"github.com/scaleway/scaleway-sdk-go/marshaler"
	"github.com/scaleway/scaleway-sdk-go/namegenerator"
	"github.com/scaleway/scaleway-sdk-go/parameter"
	"github.com/scaleway/scaleway-sdk-go/scw"
)

// always import dependencies
var (
	_ fmt.Stringer
	_ json.Unmarshaler
	_ url.URL
	_ net.IP
	_ http.Header
	_ bytes.Reader
	_ time.Time
	_ = strings.Join

	_ scw.ScalewayRequest
	_ marshaler.Duration
	_ scw.File
	_ = parameter.AddToQuery
	_ = namegenerator.GetRandomName
)

type DataKeyAlgorithmSymmetricEncryption string

const (
	DataKeyAlgorithmSymmetricEncryptionUnknownSymmetricEncryption = DataKeyAlgorithmSymmetricEncryption("unknown_symmetric_encryption")
	// Key Manager currently only supports the `AES-GCM` (256-bits) data key algorithm.
	DataKeyAlgorithmSymmetricEncryptionAes256Gcm = DataKeyAlgorithmSymmetricEncryption("aes_256_gcm")
)

func (enum DataKeyAlgorithmSymmetricEncryption) String() string {
	if enum == "" {
		// return default value if empty
		return string(DataKeyAlgorithmSymmetricEncryptionUnknownSymmetricEncryption)
	}
	return string(enum)
}

func (enum DataKeyAlgorithmSymmetricEncryption) Values() []DataKeyAlgorithmSymmetricEncryption {
	return []DataKeyAlgorithmSymmetricEncryption{
		"unknown_symmetric_encryption",
		"aes_256_gcm",
	}
}

func (enum DataKeyAlgorithmSymmetricEncryption) MarshalJSON() ([]byte, error) {
	return []byte(fmt.Sprintf(`"%s"`, enum)), nil
}

func (enum *DataKeyAlgorithmSymmetricEncryption) UnmarshalJSON(data []byte) error {
	tmp := ""

	if err := json.Unmarshal(data, &tmp); err != nil {
		return err
	}

	*enum = DataKeyAlgorithmSymmetricEncryption(DataKeyAlgorithmSymmetricEncryption(tmp).String())
	return nil
}

type KeyAlgorithmAsymmetricEncryption string

const (
	KeyAlgorithmAsymmetricEncryptionUnknownAsymmetricEncryption = KeyAlgorithmAsymmetricEncryption("unknown_asymmetric_encryption")
	// RSA-OAEP (Optimal Asymmetric Encryption Padding) with a 2048-bit key and SHA-256 hash function.
	KeyAlgorithmAsymmetricEncryptionRsaOaep2048Sha256 = KeyAlgorithmAsymmetricEncryption("rsa_oaep_2048_sha256")
	// RSA-OAEP (Optimal Asymmetric Encryption Padding) with a 3072-bit key and SHA-256 hash function (recommended).
	KeyAlgorithmAsymmetricEncryptionRsaOaep3072Sha256 = KeyAlgorithmAsymmetricEncryption("rsa_oaep_3072_sha256")
	// RSA-OAEP (Optimal Asymmetric Encryption Padding) with a 4096-bit key and SHA-256 hash function.
	KeyAlgorithmAsymmetricEncryptionRsaOaep4096Sha256 = KeyAlgorithmAsymmetricEncryption("rsa_oaep_4096_sha256")
)

func (enum KeyAlgorithmAsymmetricEncryption) String() string {
	if enum == "" {
		// return default value if empty
		return string(KeyAlgorithmAsymmetricEncryptionUnknownAsymmetricEncryption)
	}
	return string(enum)
}

func (enum KeyAlgorithmAsymmetricEncryption) Values() []KeyAlgorithmAsymmetricEncryption {
	return []KeyAlgorithmAsymmetricEncryption{
		"unknown_asymmetric_encryption",
		"rsa_oaep_2048_sha256",
		"rsa_oaep_3072_sha256",
		"rsa_oaep_4096_sha256",
	}
}

func (enum KeyAlgorithmAsymmetricEncryption) MarshalJSON() ([]byte, error) {
	return []byte(fmt.Sprintf(`"%s"`, enum)), nil
}

func (enum *KeyAlgorithmAsymmetricEncryption) UnmarshalJSON(data []byte) error {
	tmp := ""

	if err := json.Unmarshal(data, &tmp); err != nil {
		return err
	}

	*enum = KeyAlgorithmAsymmetricEncryption(KeyAlgorithmAsymmetricEncryption(tmp).String())
	return nil
}

type KeyAlgorithmAsymmetricSigning string

const (
	KeyAlgorithmAsymmetricSigningUnknownAsymmetricSigning = KeyAlgorithmAsymmetricSigning("unknown_asymmetric_signing")
	// ECDSA (Elliptic Curve Digital Signature Algorithm) on the P-256 Curve and SHA-256 hash function (recommended).
	KeyAlgorithmAsymmetricSigningEcP256Sha256 = KeyAlgorithmAsymmetricSigning("ec_p256_sha256")
	// ECDSA (Elliptic Curve Digital Signature Algorithm) on the P-384 Curve and SHA-384 hash function.
	KeyAlgorithmAsymmetricSigningEcP384Sha384 = KeyAlgorithmAsymmetricSigning("ec_p384_sha384")
	// RSA-PSS (Probabilistic Signature Scheme) with a 2048-bit key and SHA-256 hash function.
	KeyAlgorithmAsymmetricSigningRsaPss2048Sha256 = KeyAlgorithmAsymmetricSigning("rsa_pss_2048_sha256")
	// RSA-PSS (Probabilistic Signature Scheme) with a 3072-bit key and SHA-256 hash function.
	KeyAlgorithmAsymmetricSigningRsaPss3072Sha256 = KeyAlgorithmAsymmetricSigning("rsa_pss_3072_sha256")
	// RSA-PSS (Probabilistic Signature Scheme) with a 4096-bit key and SHA-256 hash function.
	KeyAlgorithmAsymmetricSigningRsaPss4096Sha256 = KeyAlgorithmAsymmetricSigning("rsa_pss_4096_sha256")
	// RSA-PKCS1 (Public Key Cryptography Standards) with a 2048-bit key and SHA-256 hash function.
	KeyAlgorithmAsymmetricSigningRsaPkcs1_2048Sha256 = KeyAlgorithmAsymmetricSigning("rsa_pkcs1_2048_sha256")
	// RSA-PKCS1 (Public Key Cryptography Standards) with a 3072-bit key and SHA-256 hash function.
	KeyAlgorithmAsymmetricSigningRsaPkcs1_3072Sha256 = KeyAlgorithmAsymmetricSigning("rsa_pkcs1_3072_sha256")
	// RSA-PKCS1 (Public Key Cryptography Standards) with a 4096-bit key and SHA-256 hash function.
	KeyAlgorithmAsymmetricSigningRsaPkcs1_4096Sha256 = KeyAlgorithmAsymmetricSigning("rsa_pkcs1_4096_sha256")
	// ML-DSA (Module-Lattice Digital Signature Algorithm) FIPS 204 post-quantum signature scheme with security category 2.
	KeyAlgorithmAsymmetricSigningMlDsa44 = KeyAlgorithmAsymmetricSigning("ml_dsa_44")
	// ML-DSA (Module-Lattice Digital Signature Algorithm) FIPS 204 post-quantum signature scheme with security category 3.
	KeyAlgorithmAsymmetricSigningMlDsa65 = KeyAlgorithmAsymmetricSigning("ml_dsa_65")
	// ML-DSA (Module-Lattice Digital Signature Algorithm) FIPS 204 post-quantum signature scheme with security category 5.
	KeyAlgorithmAsymmetricSigningMlDsa87 = KeyAlgorithmAsymmetricSigning("ml_dsa_87")
)

func (enum KeyAlgorithmAsymmetricSigning) String() string {
	if enum == "" {
		// return default value if empty
		return string(KeyAlgorithmAsymmetricSigningUnknownAsymmetricSigning)
	}
	return string(enum)
}

func (enum KeyAlgorithmAsymmetricSigning) Values() []KeyAlgorithmAsymmetricSigning {
	return []KeyAlgorithmAsymmetricSigning{
		"unknown_asymmetric_signing",
		"ec_p256_sha256",
		"ec_p384_sha384",
		"rsa_pss_2048_sha256",
		"rsa_pss_3072_sha256",
		"rsa_pss_4096_sha256",
		"rsa_pkcs1_2048_sha256",
		"rsa_pkcs1_3072_sha256",
		"rsa_pkcs1_4096_sha256",
		"ml_dsa_44",
		"ml_dsa_65",
		"ml_dsa_87",
	}
}

func (enum KeyAlgorithmAsymmetricSigning) MarshalJSON() ([]byte, error) {
	return []byte(fmt.Sprintf(`"%s"`, enum)), nil
}

func (enum *KeyAlgorithmAsymmetricSigning) UnmarshalJSON(data []byte) error {
	tmp := ""

	if err := json.Unmarshal(data, &tmp); err != nil {
		return err
	}

	*enum = KeyAlgorithmAsymmetricSigning(KeyAlgorithmAsymmetricSigning(tmp).String())
	return nil
}

type KeyAlgorithmSymmetricEncryption string

const (
	KeyAlgorithmSymmetricEncryptionUnknownSymmetricEncryption = KeyAlgorithmSymmetricEncryption("unknown_symmetric_encryption")
	// 256-bit Advanced Encryption Standard (AES-256) keys in Galois Counter Mode (GCM).
	KeyAlgorithmSymmetricEncryptionAes256Gcm = KeyAlgorithmSymmetricEncryption("aes_256_gcm")
)

func (enum KeyAlgorithmSymmetricEncryption) String() string {
	if enum == "" {
		// return default value if empty
		return string(KeyAlgorithmSymmetricEncryptionUnknownSymmetricEncryption)
	}
	return string(enum)
}

func (enum KeyAlgorithmSymmetricEncryption) Values() []KeyAlgorithmSymmetricEncryption {
	return []KeyAlgorithmSymmetricEncryption{
		"unknown_symmetric_encryption",
		"aes_256_gcm",
	}
}

func (enum KeyAlgorithmSymmetricEncryption) MarshalJSON() ([]byte, error) {
	return []byte(fmt.Sprintf(`"%s"`, enum)), nil
}

func (enum *KeyAlgorithmSymmetricEncryption) UnmarshalJSON(data []byte) error {
	tmp := ""

	if err := json.Unmarshal(data, &tmp); err != nil {
		return err
	}

	*enum = KeyAlgorithmSymmetricEncryption(KeyAlgorithmSymmetricEncryption(tmp).String())
	return nil
}

type KeyOrigin string

const (
	KeyOriginUnknownOrigin = KeyOrigin("unknown_origin")
	// Key Manager generates the key material upon key creation.
	KeyOriginScalewayKms = KeyOrigin("scaleway_kms")
	// Key Manager creates a key with key material coming from an external source.
	KeyOriginExternal = KeyOrigin("external")
)

func (enum KeyOrigin) String() string {
	if enum == "" {
		// return default value if empty
		return string(KeyOriginUnknownOrigin)
	}
	return string(enum)
}

func (enum KeyOrigin) Values() []KeyOrigin {
	return []KeyOrigin{
		"unknown_origin",
		"scaleway_kms",
		"external",
	}
}

func (enum KeyOrigin) MarshalJSON() ([]byte, error) {
	return []byte(fmt.Sprintf(`"%s"`, enum)), nil
}

func (enum *KeyOrigin) UnmarshalJSON(data []byte) error {
	tmp := ""

	if err := json.Unmarshal(data, &tmp); err != nil {
		return err
	}

	*enum = KeyOrigin(KeyOrigin(tmp).String())
	return nil
}

type KeyState string

const (
	KeyStateUnknownState = KeyState("unknown_state")
	// The key can be used for cryptographic operations.
	KeyStateEnabled = KeyState("enabled")
	// The key cannot be used for cryptographic operations.
	KeyStateDisabled = KeyState("disabled")
	// Key material must be imported before the key can be used for cryptographic operations.
	KeyStatePendingKeyMaterial   = KeyState("pending_key_material")
	KeyStateScheduledForDeletion = KeyState("scheduled_for_deletion")
)

func (enum KeyState) String() string {
	if enum == "" {
		// return default value if empty
		return string(KeyStateUnknownState)
	}
	return string(enum)
}

func (enum KeyState) Values() []KeyState {
	return []KeyState{
		"unknown_state",
		"enabled",
		"disabled",
		"pending_key_material",
		"scheduled_for_deletion",
	}
}

func (enum KeyState) MarshalJSON() ([]byte, error) {
	return []byte(fmt.Sprintf(`"%s"`, enum)), nil
}

func (enum *KeyState) UnmarshalJSON(data []byte) error {
	tmp := ""

	if err := json.Unmarshal(data, &tmp); err != nil {
		return err
	}

	*enum = KeyState(KeyState(tmp).String())
	return nil
}

type ListAlgorithmsRequestUsage string

const (
	ListAlgorithmsRequestUsageUnknownUsage         = ListAlgorithmsRequestUsage("unknown_usage")
	ListAlgorithmsRequestUsageSymmetricEncryption  = ListAlgorithmsRequestUsage("symmetric_encryption")
	ListAlgorithmsRequestUsageAsymmetricEncryption = ListAlgorithmsRequestUsage("asymmetric_encryption")
	ListAlgorithmsRequestUsageAsymmetricSigning    = ListAlgorithmsRequestUsage("asymmetric_signing")
)

func (enum ListAlgorithmsRequestUsage) String() string {
	if enum == "" {
		// return default value if empty
		return string(ListAlgorithmsRequestUsageUnknownUsage)
	}
	return string(enum)
}

func (enum ListAlgorithmsRequestUsage) Values() []ListAlgorithmsRequestUsage {
	return []ListAlgorithmsRequestUsage{
		"unknown_usage",
		"symmetric_encryption",
		"asymmetric_encryption",
		"asymmetric_signing",
	}
}

func (enum ListAlgorithmsRequestUsage) MarshalJSON() ([]byte, error) {
	return []byte(fmt.Sprintf(`"%s"`, enum)), nil
}

func (enum *ListAlgorithmsRequestUsage) UnmarshalJSON(data []byte) error {
	tmp := ""

	if err := json.Unmarshal(data, &tmp); err != nil {
		return err
	}

	*enum = ListAlgorithmsRequestUsage(ListAlgorithmsRequestUsage(tmp).String())
	return nil
}

type ListKeysRequestOrderBy string

const (
	ListKeysRequestOrderByNameAsc       = ListKeysRequestOrderBy("name_asc")
	ListKeysRequestOrderByNameDesc      = ListKeysRequestOrderBy("name_desc")
	ListKeysRequestOrderByCreatedAtAsc  = ListKeysRequestOrderBy("created_at_asc")
	ListKeysRequestOrderByCreatedAtDesc = ListKeysRequestOrderBy("created_at_desc")
	ListKeysRequestOrderByUpdatedAtAsc  = ListKeysRequestOrderBy("updated_at_asc")
	ListKeysRequestOrderByUpdatedAtDesc = ListKeysRequestOrderBy("updated_at_desc")
)

func (enum ListKeysRequestOrderBy) String() string {
	if enum == "" {
		// return default value if empty
		return string(ListKeysRequestOrderByNameAsc)
	}
	return string(enum)
}

func (enum ListKeysRequestOrderBy) Values() []ListKeysRequestOrderBy {
	return []ListKeysRequestOrderBy{
		"name_asc",
		"name_desc",
		"created_at_asc",
		"created_at_desc",
		"updated_at_asc",
		"updated_at_desc",
	}
}

func (enum ListKeysRequestOrderBy) MarshalJSON() ([]byte, error) {
	return []byte(fmt.Sprintf(`"%s"`, enum)), nil
}

func (enum *ListKeysRequestOrderBy) UnmarshalJSON(data []byte) error {
	tmp := ""

	if err := json.Unmarshal(data, &tmp); err != nil {
		return err
	}

	*enum = ListKeysRequestOrderBy(ListKeysRequestOrderBy(tmp).String())
	return nil
}

type ListKeysRequestUsage string

const (
	ListKeysRequestUsageUnknownUsage         = ListKeysRequestUsage("unknown_usage")
	ListKeysRequestUsageSymmetricEncryption  = ListKeysRequestUsage("symmetric_encryption")
	ListKeysRequestUsageAsymmetricEncryption = ListKeysRequestUsage("asymmetric_encryption")
	ListKeysRequestUsageAsymmetricSigning    = ListKeysRequestUsage("asymmetric_signing")
)

func (enum ListKeysRequestUsage) String() string {
	if enum == "" {
		// return default value if empty
		return string(ListKeysRequestUsageUnknownUsage)
	}
	return string(enum)
}

func (enum ListKeysRequestUsage) Values() []ListKeysRequestUsage {
	return []ListKeysRequestUsage{
		"unknown_usage",
		"symmetric_encryption",
		"asymmetric_encryption",
		"asymmetric_signing",
	}
}

func (enum ListKeysRequestUsage) MarshalJSON() ([]byte, error) {
	return []byte(fmt.Sprintf(`"%s"`, enum)), nil
}

func (enum *ListKeysRequestUsage) UnmarshalJSON(data []byte) error {
	tmp := ""

	if err := json.Unmarshal(data, &tmp); err != nil {
		return err
	}

	*enum = ListKeysRequestUsage(ListKeysRequestUsage(tmp).String())
	return nil
}

// KeyRotationPolicy: key rotation policy.
type KeyRotationPolicy struct {
	// RotationPeriod: time interval between two key rotations. The minimum duration is 24 hours and the maximum duration is 1 year (876000 hours).
	RotationPeriod *scw.Duration `json:"rotation_period"`

	// NextRotationAt: timestamp indicating the next scheduled rotation.
	NextRotationAt *time.Time `json:"next_rotation_at"`
}

// KeyUsage: key usage.
type KeyUsage struct {
	// SymmetricEncryption: see the `Key.Algorithm.SymmetricEncryption` enum for a description of values.
	// Default value: unknown_symmetric_encryption
	// Precisely one of SymmetricEncryption, AsymmetricEncryption, AsymmetricSigning must be set.
	SymmetricEncryption *KeyAlgorithmSymmetricEncryption `json:"symmetric_encryption,omitempty"`

	// AsymmetricEncryption: see the `Key.Algorithm.AsymmetricEncryption` enum for a description of values.
	// Default value: unknown_asymmetric_encryption
	// Precisely one of SymmetricEncryption, AsymmetricEncryption, AsymmetricSigning must be set.
	AsymmetricEncryption *KeyAlgorithmAsymmetricEncryption `json:"asymmetric_encryption,omitempty"`

	// AsymmetricSigning: see the `Key.Algorithm.AsymmetricSigning` enum for a description of values.
	// Default value: unknown_asymmetric_signing
	// Precisely one of SymmetricEncryption, AsymmetricEncryption, AsymmetricSigning must be set.
	AsymmetricSigning *KeyAlgorithmAsymmetricSigning `json:"asymmetric_signing,omitempty"`
}

// ListAlgorithmsResponseAlgorithm: list algorithms response algorithm.
type ListAlgorithmsResponseAlgorithm struct {
	Usage string `json:"usage"`

	Name string `json:"name"`

	Recommended bool `json:"recommended"`
}

// Key: key.
type Key struct {
	// ID: ID of the key.
	ID string `json:"id"`

	// ProjectID: ID of the Project containing the key.
	ProjectID string `json:"project_id"`

	// Name: name of the key.
	Name string `json:"name"`

	// Usage: see the `Key.Usage` enum for a description of possible values.
	Usage *KeyUsage `json:"usage"`

	// State: see the `Key.State` enum for a description of possible values.
	// Default value: unknown_state
	State KeyState `json:"state"`

	// RotationCount: the rotation count tracks the number of times the key has been rotated.
	RotationCount uint32 `json:"rotation_count"`

	// CreatedAt: key creation date.
	CreatedAt *time.Time `json:"created_at"`

	// UpdatedAt: key last modification date.
	UpdatedAt *time.Time `json:"updated_at"`

	// Protected: returns `true` if key protection is applied to the key.
	Protected bool `json:"protected"`

	// Locked: returns `true` if the key is locked.
	Locked bool `json:"locked"`

	// Description: description of the key.
	Description *string `json:"description"`

	// Tags: list of the key's tags.
	Tags []string `json:"tags"`

	// RotatedAt: key last rotation date.
	RotatedAt *time.Time `json:"rotated_at"`

	// RotationPolicy: key rotation policy.
	RotationPolicy *KeyRotationPolicy `json:"rotation_policy"`

	// Origin: refer to the `Key.Origin` enum for a description of values.
	// Default value: unknown_origin
	Origin KeyOrigin `json:"origin"`

	// DeletionRequestedAt: returns the time at which deletion was requested.
	DeletionRequestedAt *time.Time `json:"deletion_requested_at"`

	// Region: region where the key is stored.
	Region scw.Region `json:"region"`

	// This field is automatically generated, do not edit it
	Srn string `json:"srn,omitempty"`
}

func (m *Key) setSRN(platform string) {
	if m.Srn != "" {
		// if the field is set server-side, trust the server
		return
	}
	data := struct {
		Key
		Platform string
	}{
		Key:      *m,
		Platform: platform,
	}

	notEmpty := func(a any) (string, error) {
		s := fmt.Sprint(a)
		if s == "" {
			return "", errors.New("value is empty")
		}
		return s, nil
	}
	templ := "srn://key-manager.{{ notempty .Platform }}/regions/{{ notempty .Region }}/keys/{{ notempty .ID }}"
	t, err := template.New("srn").Funcs(template.FuncMap{"notempty": notEmpty}).Parse(templ)
	if err != nil {
		return
	}
	var out bytes.Buffer
	if err := t.Execute(&out, data); err == nil {
		m.Srn = out.String()
	}
	// note: if the error was not nil, we simply don't set the SRN
}

// CreateKeyRequest: create key request.
type CreateKeyRequest struct {
	// Region: region to target. If none is passed will use default region from the config.
	Region scw.Region `json:"-"`

	// ProjectID: ID of the Project containing the key.
	ProjectID string `json:"project_id"`

	// Name: (Optional) Name of the key.
	Name *string `json:"name,omitempty"`

	// Usage: see the `Key.Usage` enum for a description of possible values.
	Usage *KeyUsage `json:"usage,omitempty"`

	// Description: (Optional) Description of the key.
	Description *string `json:"description,omitempty"`

	// Tags: (Optional) List of the key's tags.
	Tags []string `json:"tags"`

	// RotationPolicy: if not specified, no rotation policy will be applied to the key.
	RotationPolicy *KeyRotationPolicy `json:"rotation_policy,omitempty"`

	// Unprotected: default value is `false`.
	Unprotected bool `json:"unprotected"`

	// Origin: refer to the `Key.Origin` enum for a description of values.
	// Default value: unknown_origin
	Origin KeyOrigin `json:"origin"`
}

// DataKey: data key.
type DataKey struct {
	// KeyID: ID of the data encryption key.
	KeyID string `json:"key_id"`

	// Algorithm: symmetric encryption algorithm of the data encryption key (`AES-256-GCM`).
	// Default value: unknown_symmetric_encryption
	Algorithm DataKeyAlgorithmSymmetricEncryption `json:"algorithm"`

	// Ciphertext: your data encryption key's ciphertext can be stored safely. It can only be decrypted through the keys you create in Key Manager, using the relevant key ID.
	Ciphertext []byte `json:"ciphertext"`

	// Plaintext: (Optional) Your data encryption key's plaintext allows you to use the key immediately upon creation. It must neither be stored or shared.
	Plaintext *[]byte `json:"plaintext"`

	// CreatedAt: data encryption key creation date.
	CreatedAt *time.Time `json:"created_at"`
}

// DecryptRequest: decrypt request.
type DecryptRequest struct {
	// Region: region to target. If none is passed will use default region from the config.
	Region scw.Region `json:"-"`

	// KeyID: the key must have an usage set to `symmetric_encryption` or `asymmetric_encryption`.
	KeyID string `json:"-"`

	// Ciphertext: data size must be between 1 and 131071 bytes.
	Ciphertext []byte `json:"ciphertext"`

	// AssociatedData: the additional data must match the value passed in the encryption request. Only supported by keys with a usage set to `symmetric_encryption`.
	AssociatedData *[]byte `json:"associated_data,omitempty"`
}

// DecryptResponse: decrypt response.
type DecryptResponse struct {
	// KeyID: ID of the key used for decryption.
	KeyID string `json:"key_id"`

	// Plaintext: key's decrypted data.
	Plaintext []byte `json:"plaintext"`

	// Ciphertext: if the data was already encrypted with the latest key rotation, no output will be returned in the response object.
	Ciphertext *[]byte `json:"ciphertext"`
}

// DeleteKeyMaterialRequest: delete key material request.
type DeleteKeyMaterialRequest struct {
	// Region: region to target. If none is passed will use default region from the config.
	Region scw.Region `json:"-"`

	// KeyID: ID of the key of which to delete the key material.
	KeyID string `json:"-"`
}

// DeleteKeyRequest: delete key request.
type DeleteKeyRequest struct {
	// Region: region to target. If none is passed will use default region from the config.
	Region scw.Region `json:"-"`

	// KeyID: ID of the key to delete.
	KeyID string `json:"-"`
}

// DisableKeyRequest: disable key request.
type DisableKeyRequest struct {
	// Region: region to target. If none is passed will use default region from the config.
	Region scw.Region `json:"-"`

	// KeyID: ID of the key to disable.
	KeyID string `json:"-"`
}

// EnableKeyRequest: enable key request.
type EnableKeyRequest struct {
	// Region: region to target. If none is passed will use default region from the config.
	Region scw.Region `json:"-"`

	// KeyID: ID of the key to enable.
	KeyID string `json:"-"`
}

// EncryptRequest: encrypt request.
type EncryptRequest struct {
	// Region: region to target. If none is passed will use default region from the config.
	Region scw.Region `json:"-"`

	// KeyID: the key must have an usage set to `symmetric_encryption` or `asymmetric_encryption`.
	KeyID string `json:"-"`

	// Plaintext: data size must be between 1 and 65535 bytes.
	Plaintext []byte `json:"plaintext"`

	// AssociatedData: additional data which will not be encrypted, but authenticated and appended to the encrypted payload. Only supported by keys with a usage set to `symmetric_encryption`.
	AssociatedData *[]byte `json:"associated_data,omitempty"`
}

// EncryptResponse: encrypt response.
type EncryptResponse struct {
	// KeyID: ID of the key used for encryption.
	KeyID string `json:"key_id"`

	// Ciphertext: key's encrypted data.
	Ciphertext []byte `json:"ciphertext"`
}

// GenerateDataKeyRequest: generate data key request.
type GenerateDataKeyRequest struct {
	// Region: region to target. If none is passed will use default region from the config.
	Region scw.Region `json:"-"`

	// KeyID: ID of the key.
	KeyID string `json:"-"`

	// Algorithm: see the `DataKey.Algorithm.SymmetricEncryption` enum for a description of values.
	// Default value: unknown_symmetric_encryption
	Algorithm DataKeyAlgorithmSymmetricEncryption `json:"algorithm"`

	// WithoutPlaintext: default value is `false`, meaning that the plaintext is returned.
	// Set it to `true` if you do not wish the plaintext to be returned in the response object.
	WithoutPlaintext bool `json:"without_plaintext"`
}

// GetKeyRequest: get key request.
type GetKeyRequest struct {
	// Region: region to target. If none is passed will use default region from the config.
	Region scw.Region `json:"-"`

	// KeyID: ID of the key to target.
	KeyID string `json:"-"`
}

// GetPublicKeyRequest: get public key request.
type GetPublicKeyRequest struct {
	// Region: region to target. If none is passed will use default region from the config.
	Region scw.Region `json:"-"`

	// KeyID: ID of the key.
	KeyID string `json:"-"`
}

// ImportKeyMaterialRequest: import key material request.
type ImportKeyMaterialRequest struct {
	// Region: region to target. If none is passed will use default region from the config.
	Region scw.Region `json:"-"`

	// KeyID: the key's origin must be `external`.
	KeyID string `json:"-"`

	// KeyMaterial: the key material is a random sequence of bytes used to derive a cryptographic key.
	KeyMaterial []byte `json:"key_material"`

	// Salt: a salt is random data added to key material to ensure unique derived keys, even if the input is similar. It helps strengthen security when the key material has low randomness (low entropy).
	Salt *[]byte `json:"salt,omitempty"`
}

// ListAlgorithmsRequest: list algorithms request.
type ListAlgorithmsRequest struct {
	// Region: region to target. If none is passed will use default region from the config.
	Region scw.Region `json:"-"`

	// Usages: filter by key usage.
	Usages []ListAlgorithmsRequestUsage `json:"usages"`
}

// ListAlgorithmsResponse: list algorithms response.
type ListAlgorithmsResponse struct {
	// Algorithms: returns a list of algorithms matching the requested criteria.
	Algorithms []*ListAlgorithmsResponseAlgorithm `json:"algorithms"`
}

// ListKeysRequest: list keys request.
type ListKeysRequest struct {
	// Region: region to target. If none is passed will use default region from the config.
	Region scw.Region `json:"-"`

	// OrganizationID: (Optional) Filter by Organization ID.
	OrganizationID *string `json:"-"`

	// ProjectID: (Optional) Filter by Project ID.
	ProjectID *string `json:"-"`

	// OrderBy: default value: name_asc
	OrderBy ListKeysRequestOrderBy `json:"-"`

	Page *int32 `json:"-"`

	PageSize *uint32 `json:"-"`

	// Tags: (Optional) List of tags to filter on.
	Tags []string `json:"-"`

	// Name: (Optional) Filter by key name.
	Name *string `json:"-"`

	// Usage: select from symmetric encryption, asymmetric encryption, or asymmetric signing.
	// Default value: unknown_usage
	Usage ListKeysRequestUsage `json:"-"`

	// ScheduledForDeletion: filter keys based on their deletion status. By default, only keys not scheduled for deletion are returned in the output.
	ScheduledForDeletion bool `json:"-"`
}

// ListKeysResponse: list keys response.
type ListKeysResponse struct {
	// Keys: single page of keys matching the requested criteria.
	Keys []*Key `json:"keys"`

	// TotalCount: total count of keys matching the requested criteria.
	TotalCount uint64 `json:"total_count"`
}

// UnsafeGetTotalCount should not be used
// Internal usage only
func (r *ListKeysResponse) UnsafeGetTotalCount() uint64 {
	return r.TotalCount
}

// UnsafeAppend should not be used
// Internal usage only
func (r *ListKeysResponse) UnsafeAppend(res any) (uint64, error) {
	results, ok := res.(*ListKeysResponse)
	if !ok {
		return 0, errors.New("%T type cannot be appended to type %T", res, r)
	}

	r.Keys = append(r.Keys, results.Keys...)
	r.TotalCount += uint64(len(results.Keys))
	return uint64(len(results.Keys)), nil
}

// ProtectKeyRequest: protect key request.
type ProtectKeyRequest struct {
	// Region: region to target. If none is passed will use default region from the config.
	Region scw.Region `json:"-"`

	// KeyID: ID of the key to apply key protection to.
	KeyID string `json:"-"`
}

// PublicKey: public key.
type PublicKey struct {
	Pem string `json:"pem"`
}

// RestoreKeyRequest: restore key request.
type RestoreKeyRequest struct {
	// Region: region to target. If none is passed will use default region from the config.
	Region scw.Region `json:"-"`

	KeyID string `json:"-"`
}

// RotateKeyRequest: rotate key request.
type RotateKeyRequest struct {
	// Region: region to target. If none is passed will use default region from the config.
	Region scw.Region `json:"-"`

	// KeyID: ID of the key to rotate.
	KeyID string `json:"-"`
}

// SignRequest: sign request.
type SignRequest struct {
	// Region: region to target. If none is passed will use default region from the config.
	Region scw.Region `json:"-"`

	// KeyID: ID of the key to use for signing.
	KeyID string `json:"-"`

	// Digest: the digest must be generated using the same algorithm defined in the key’s algorithm settings.
	Digest []byte `json:"digest"`
}

// SignResponse: sign response.
type SignResponse struct {
	// KeyID: ID of the key used to generate the signature.
	KeyID string `json:"key_id"`

	// Signature: the message signature.
	Signature []byte `json:"signature"`
}

// UnprotectKeyRequest: unprotect key request.
type UnprotectKeyRequest struct {
	// Region: region to target. If none is passed will use default region from the config.
	Region scw.Region `json:"-"`

	// KeyID: ID of the key to remove key protection from.
	KeyID string `json:"-"`
}

// UpdateKeyRequest: update key request.
type UpdateKeyRequest struct {
	// Region: region to target. If none is passed will use default region from the config.
	Region scw.Region `json:"-"`

	// KeyID: ID of the key to update.
	KeyID string `json:"-"`

	// Name: (Optional) Updated name of the key.
	Name *string `json:"name,omitempty"`

	// Description: (Optional) Updated description of the key.
	Description *string `json:"description,omitempty"`

	// Tags: (Optional) Updated list of the key's tags.
	Tags *[]string `json:"tags,omitempty"`

	// RotationPolicy: if not specified, the key's existing rotation policy applies.
	RotationPolicy *KeyRotationPolicy `json:"rotation_policy,omitempty"`
}

// VerifyRequest: verify request.
type VerifyRequest struct {
	// Region: region to target. If none is passed will use default region from the config.
	Region scw.Region `json:"-"`

	// KeyID: ID of the key to use for signature verification.
	KeyID string `json:"-"`

	// Digest: must be generated using the same algorithm specified in the key’s configuration.
	Digest []byte `json:"digest"`

	// Signature: the message signature to verify.
	Signature []byte `json:"signature"`
}

// VerifyResponse: verify response.
type VerifyResponse struct {
	// KeyID: ID of the key used for verification.
	KeyID string `json:"key_id"`

	// Valid: returns `true` if the signature is valid for the digest and key, and `false` otherwise.
	Valid bool `json:"valid"`
}

// This API allows you to create, manage and use cryptographic keys in a centralized and secure service.
type API struct {
	client *scw.Client
}

// NewAPI returns a API object from a Scaleway client.
func NewAPI(client *scw.Client) *API {
	return &API{
		client: client,
	}
}

func (s *API) Regions() []scw.Region {
	return []scw.Region{scw.RegionFrPar, scw.RegionNlAms, scw.RegionPlWaw}
}

// CreateKey: Create a key in a given region specified by the `region` parameter. You can use keys to encrypt or decrypt arbitrary payloads, to sign and verify messages or to generate data encryption keys. **Data encryption keys are not stored in Key Manager**.
func (s *API) CreateKey(req *CreateKeyRequest, opts ...scw.RequestOption) (*Key, error) {
	var err error

	if req.Region == "" {
		defaultRegion, _ := s.client.GetDefaultRegion()
		req.Region = defaultRegion
	}

	if req.ProjectID == "" {
		defaultProjectID, _ := s.client.GetDefaultProjectID()
		req.ProjectID = defaultProjectID
	}

	if fmt.Sprint(req.Region) == "" {
		return nil, errors.New("field Region cannot be empty in request")
	}

	scwReq := &scw.ScalewayRequest{
		Method: "POST",
		Path:   "/key-manager/v1alpha1/regions/" + fmt.Sprint(req.Region) + "/keys",
	}

	err = scwReq.SetBody(req)
	if err != nil {
		return nil, err
	}

	var resp Key

	err = s.client.Do(scwReq, &resp, opts...)
	if err != nil {
		return nil, err
	}
	// platform := s.client.GetPlatform()
	platform := "scw.eu"
	resp.setSRN(platform)
	return &resp, nil
}

// GetKey: Retrieve metadata for a specified key using the `region` and `key_id` parameters.
func (s *API) GetKey(req *GetKeyRequest, opts ...scw.RequestOption) (*Key, error) {
	var err error

	if req.Region == "" {
		defaultRegion, _ := s.client.GetDefaultRegion()
		req.Region = defaultRegion
	}

	if fmt.Sprint(req.Region) == "" {
		return nil, errors.New("field Region cannot be empty in request")
	}

	if fmt.Sprint(req.KeyID) == "" {
		return nil, errors.New("field KeyID cannot be empty in request")
	}

	scwReq := &scw.ScalewayRequest{
		Method: "GET",
		Path:   "/key-manager/v1alpha1/regions/" + fmt.Sprint(req.Region) + "/keys/" + fmt.Sprint(req.KeyID) + "",
	}

	var resp Key

	err = s.client.Do(scwReq, &resp, opts...)
	if err != nil {
		return nil, err
	}
	// platform := s.client.GetPlatform()
	platform := "scw.eu"
	resp.setSRN(platform)
	return &resp, nil
}

// GetPublicKey: Retrieves the public portion of an asymmetric cryptographic key in PEM format.
func (s *API) GetPublicKey(req *GetPublicKeyRequest, opts ...scw.RequestOption) (*PublicKey, error) {
	var err error

	if req.Region == "" {
		defaultRegion, _ := s.client.GetDefaultRegion()
		req.Region = defaultRegion
	}

	if fmt.Sprint(req.Region) == "" {
		return nil, errors.New("field Region cannot be empty in request")
	}

	if fmt.Sprint(req.KeyID) == "" {
		return nil, errors.New("field KeyID cannot be empty in request")
	}

	scwReq := &scw.ScalewayRequest{
		Method: "GET",
		Path:   "/key-manager/v1alpha1/regions/" + fmt.Sprint(req.Region) + "/keys/" + fmt.Sprint(req.KeyID) + "/public-key",
	}

	var resp PublicKey

	err = s.client.Do(scwReq, &resp, opts...)
	if err != nil {
		return nil, err
	}
	return &resp, nil
}

// UpdateKey: Modify a key's metadata including name, description and tags, specified by the `key_id` and `region` parameters.
func (s *API) UpdateKey(req *UpdateKeyRequest, opts ...scw.RequestOption) (*Key, error) {
	var err error

	if req.Region == "" {
		defaultRegion, _ := s.client.GetDefaultRegion()
		req.Region = defaultRegion
	}

	if fmt.Sprint(req.Region) == "" {
		return nil, errors.New("field Region cannot be empty in request")
	}

	if fmt.Sprint(req.KeyID) == "" {
		return nil, errors.New("field KeyID cannot be empty in request")
	}

	scwReq := &scw.ScalewayRequest{
		Method: "PATCH",
		Path:   "/key-manager/v1alpha1/regions/" + fmt.Sprint(req.Region) + "/keys/" + fmt.Sprint(req.KeyID) + "",
	}

	err = scwReq.SetBody(req)
	if err != nil {
		return nil, err
	}

	var resp Key

	err = s.client.Do(scwReq, &resp, opts...)
	if err != nil {
		return nil, err
	}
	// platform := s.client.GetPlatform()
	platform := "scw.eu"
	resp.setSRN(platform)
	return &resp, nil
}

// DeleteKey: Permanently delete a key specified by the `region` and `key_id` parameters. This action is irreversible. Any data encrypted with this key, including data encryption keys, will no longer be decipherable.
func (s *API) DeleteKey(req *DeleteKeyRequest, opts ...scw.RequestOption) error {
	var err error

	if req.Region == "" {
		defaultRegion, _ := s.client.GetDefaultRegion()
		req.Region = defaultRegion
	}

	if fmt.Sprint(req.Region) == "" {
		return errors.New("field Region cannot be empty in request")
	}

	if fmt.Sprint(req.KeyID) == "" {
		return errors.New("field KeyID cannot be empty in request")
	}

	scwReq := &scw.ScalewayRequest{
		Method: "DELETE",
		Path:   "/key-manager/v1alpha1/regions/" + fmt.Sprint(req.Region) + "/keys/" + fmt.Sprint(req.KeyID) + "",
	}

	err = s.client.Do(scwReq, nil, opts...)
	if err != nil {
		return err
	}
	return nil
}

// RotateKey: Generate a new version of an existing key with new key material. Previous key versions remain usable to decrypt previously encrypted data, but the key's new version will be used for subsequent encryption operations and data key generation.
func (s *API) RotateKey(req *RotateKeyRequest, opts ...scw.RequestOption) (*Key, error) {
	var err error

	if req.Region == "" {
		defaultRegion, _ := s.client.GetDefaultRegion()
		req.Region = defaultRegion
	}

	if fmt.Sprint(req.Region) == "" {
		return nil, errors.New("field Region cannot be empty in request")
	}

	if fmt.Sprint(req.KeyID) == "" {
		return nil, errors.New("field KeyID cannot be empty in request")
	}

	scwReq := &scw.ScalewayRequest{
		Method: "POST",
		Path:   "/key-manager/v1alpha1/regions/" + fmt.Sprint(req.Region) + "/keys/" + fmt.Sprint(req.KeyID) + "/rotate",
	}

	err = scwReq.SetBody(req)
	if err != nil {
		return nil, err
	}

	var resp Key

	err = s.client.Do(scwReq, &resp, opts...)
	if err != nil {
		return nil, err
	}
	// platform := s.client.GetPlatform()
	platform := "scw.eu"
	resp.setSRN(platform)
	return &resp, nil
}

// ProtectKey: Apply protection to a given key specified by the `key_id` parameter. Applying key protection means that your key can be used and modified, but it cannot be deleted.
func (s *API) ProtectKey(req *ProtectKeyRequest, opts ...scw.RequestOption) (*Key, error) {
	var err error

	if req.Region == "" {
		defaultRegion, _ := s.client.GetDefaultRegion()
		req.Region = defaultRegion
	}

	if fmt.Sprint(req.Region) == "" {
		return nil, errors.New("field Region cannot be empty in request")
	}

	if fmt.Sprint(req.KeyID) == "" {
		return nil, errors.New("field KeyID cannot be empty in request")
	}

	scwReq := &scw.ScalewayRequest{
		Method: "POST",
		Path:   "/key-manager/v1alpha1/regions/" + fmt.Sprint(req.Region) + "/keys/" + fmt.Sprint(req.KeyID) + "/protect",
	}

	err = scwReq.SetBody(req)
	if err != nil {
		return nil, err
	}

	var resp Key

	err = s.client.Do(scwReq, &resp, opts...)
	if err != nil {
		return nil, err
	}
	// platform := s.client.GetPlatform()
	platform := "scw.eu"
	resp.setSRN(platform)
	return &resp, nil
}

// UnprotectKey: Remove key protection from a given key specified by the `key_id` parameter. Removing key protection means that your key can be deleted anytime.
func (s *API) UnprotectKey(req *UnprotectKeyRequest, opts ...scw.RequestOption) (*Key, error) {
	var err error

	if req.Region == "" {
		defaultRegion, _ := s.client.GetDefaultRegion()
		req.Region = defaultRegion
	}

	if fmt.Sprint(req.Region) == "" {
		return nil, errors.New("field Region cannot be empty in request")
	}

	if fmt.Sprint(req.KeyID) == "" {
		return nil, errors.New("field KeyID cannot be empty in request")
	}

	scwReq := &scw.ScalewayRequest{
		Method: "POST",
		Path:   "/key-manager/v1alpha1/regions/" + fmt.Sprint(req.Region) + "/keys/" + fmt.Sprint(req.KeyID) + "/unprotect",
	}

	err = scwReq.SetBody(req)
	if err != nil {
		return nil, err
	}

	var resp Key

	err = s.client.Do(scwReq, &resp, opts...)
	if err != nil {
		return nil, err
	}
	// platform := s.client.GetPlatform()
	platform := "scw.eu"
	resp.setSRN(platform)
	return &resp, nil
}

// EnableKey: Enable a given key to be used for cryptographic operations. Enabling a key allows you to make a disabled key usable again. You must specify the `region` and `key_id` parameters.
func (s *API) EnableKey(req *EnableKeyRequest, opts ...scw.RequestOption) (*Key, error) {
	var err error

	if req.Region == "" {
		defaultRegion, _ := s.client.GetDefaultRegion()
		req.Region = defaultRegion
	}

	if fmt.Sprint(req.Region) == "" {
		return nil, errors.New("field Region cannot be empty in request")
	}

	if fmt.Sprint(req.KeyID) == "" {
		return nil, errors.New("field KeyID cannot be empty in request")
	}

	scwReq := &scw.ScalewayRequest{
		Method: "POST",
		Path:   "/key-manager/v1alpha1/regions/" + fmt.Sprint(req.Region) + "/keys/" + fmt.Sprint(req.KeyID) + "/enable",
	}

	err = scwReq.SetBody(req)
	if err != nil {
		return nil, err
	}

	var resp Key

	err = s.client.Do(scwReq, &resp, opts...)
	if err != nil {
		return nil, err
	}
	// platform := s.client.GetPlatform()
	platform := "scw.eu"
	resp.setSRN(platform)
	return &resp, nil
}

// DisableKey: Disable a given key, preventing it to be used for cryptographic operations. Disabling a key renders it unusable. You must specify the `region` and `key_id` parameters.
func (s *API) DisableKey(req *DisableKeyRequest, opts ...scw.RequestOption) (*Key, error) {
	var err error

	if req.Region == "" {
		defaultRegion, _ := s.client.GetDefaultRegion()
		req.Region = defaultRegion
	}

	if fmt.Sprint(req.Region) == "" {
		return nil, errors.New("field Region cannot be empty in request")
	}

	if fmt.Sprint(req.KeyID) == "" {
		return nil, errors.New("field KeyID cannot be empty in request")
	}

	scwReq := &scw.ScalewayRequest{
		Method: "POST",
		Path:   "/key-manager/v1alpha1/regions/" + fmt.Sprint(req.Region) + "/keys/" + fmt.Sprint(req.KeyID) + "/disable",
	}

	err = scwReq.SetBody(req)
	if err != nil {
		return nil, err
	}

	var resp Key

	err = s.client.Do(scwReq, &resp, opts...)
	if err != nil {
		return nil, err
	}
	// platform := s.client.GetPlatform()
	platform := "scw.eu"
	resp.setSRN(platform)
	return &resp, nil
}

// ListKeys: Retrieve a list of keys across all Projects in an Organization or within a specific Project.
// If the user has permissions for all current and future projects: Either organization_id or project_id is required.
// If the user has permissions for all current projects or only specific projects: The project_id is required.
// The `region` parameter in path is needed in both case.
func (s *API) ListKeys(req *ListKeysRequest, opts ...scw.RequestOption) (*ListKeysResponse, error) {
	var err error

	if req.Region == "" {
		defaultRegion, _ := s.client.GetDefaultRegion()
		req.Region = defaultRegion
	}

	defaultPageSize, exist := s.client.GetDefaultPageSize()
	if (req.PageSize == nil || *req.PageSize == 0) && exist {
		req.PageSize = &defaultPageSize
	}

	query := url.Values{}
	parameter.AddToQuery(query, "organization_id", req.OrganizationID)
	parameter.AddToQuery(query, "project_id", req.ProjectID)
	parameter.AddToQuery(query, "order_by", req.OrderBy)
	parameter.AddToQuery(query, "page", req.Page)
	parameter.AddToQuery(query, "page_size", req.PageSize)
	parameter.AddToQuery(query, "tags", req.Tags)
	parameter.AddToQuery(query, "name", req.Name)
	parameter.AddToQuery(query, "usage", req.Usage)
	parameter.AddToQuery(query, "scheduled_for_deletion", req.ScheduledForDeletion)

	if fmt.Sprint(req.Region) == "" {
		return nil, errors.New("field Region cannot be empty in request")
	}

	scwReq := &scw.ScalewayRequest{
		Method: "GET",
		Path:   "/key-manager/v1alpha1/regions/" + fmt.Sprint(req.Region) + "/keys",
		Query:  query,
	}

	var resp ListKeysResponse

	err = s.client.Do(scwReq, &resp, opts...)
	if err != nil {
		return nil, err
	}
	// platform := s.client.GetPlatform()
	platform := "scw.eu"
	for _, el := range resp.Keys {
		el.setSRN(platform)
	}
	return &resp, nil
}

// GenerateDataKey: Create a new data encryption key for cryptographic operations outside of Key Manager. The data encryption key is encrypted and must be decrypted using the key you have created in Key Manager.
//
// The data encryption key is returned in plaintext and ciphertext but it should only be stored in its encrypted form (ciphertext). Key Manager does not store your data encryption key. To retrieve your key's plaintext, use the `Decrypt` method with your key's ID and ciphertext.
func (s *API) GenerateDataKey(req *GenerateDataKeyRequest, opts ...scw.RequestOption) (*DataKey, error) {
	var err error

	if req.Region == "" {
		defaultRegion, _ := s.client.GetDefaultRegion()
		req.Region = defaultRegion
	}

	if fmt.Sprint(req.Region) == "" {
		return nil, errors.New("field Region cannot be empty in request")
	}

	if fmt.Sprint(req.KeyID) == "" {
		return nil, errors.New("field KeyID cannot be empty in request")
	}

	scwReq := &scw.ScalewayRequest{
		Method: "POST",
		Path:   "/key-manager/v1alpha1/regions/" + fmt.Sprint(req.Region) + "/keys/" + fmt.Sprint(req.KeyID) + "/generate-data-key",
	}

	err = scwReq.SetBody(req)
	if err != nil {
		return nil, err
	}

	var resp DataKey

	err = s.client.Do(scwReq, &resp, opts...)
	if err != nil {
		return nil, err
	}
	return &resp, nil
}

// Encrypt: Encrypt a payload using an existing key, specified by the `key_id` parameter. The maximum payload size that can be encrypted is 64 KB of plaintext.
func (s *API) Encrypt(req *EncryptRequest, opts ...scw.RequestOption) (*EncryptResponse, error) {
	var err error

	if req.Region == "" {
		defaultRegion, _ := s.client.GetDefaultRegion()
		req.Region = defaultRegion
	}

	if fmt.Sprint(req.Region) == "" {
		return nil, errors.New("field Region cannot be empty in request")
	}

	if fmt.Sprint(req.KeyID) == "" {
		return nil, errors.New("field KeyID cannot be empty in request")
	}

	scwReq := &scw.ScalewayRequest{
		Method: "POST",
		Path:   "/key-manager/v1alpha1/regions/" + fmt.Sprint(req.Region) + "/keys/" + fmt.Sprint(req.KeyID) + "/encrypt",
	}

	err = scwReq.SetBody(req)
	if err != nil {
		return nil, err
	}

	var resp EncryptResponse

	err = s.client.Do(scwReq, &resp, opts...)
	if err != nil {
		return nil, err
	}
	return &resp, nil
}

// Decrypt: Decrypt an encrypted payload using an existing key, specified by the `key_id` parameter. The maximum payload size that can be decrypted is equivalent to the encrypted output of 64 KB of data (around 131 KB).
func (s *API) Decrypt(req *DecryptRequest, opts ...scw.RequestOption) (*DecryptResponse, error) {
	var err error

	if req.Region == "" {
		defaultRegion, _ := s.client.GetDefaultRegion()
		req.Region = defaultRegion
	}

	if fmt.Sprint(req.Region) == "" {
		return nil, errors.New("field Region cannot be empty in request")
	}

	if fmt.Sprint(req.KeyID) == "" {
		return nil, errors.New("field KeyID cannot be empty in request")
	}

	scwReq := &scw.ScalewayRequest{
		Method: "POST",
		Path:   "/key-manager/v1alpha1/regions/" + fmt.Sprint(req.Region) + "/keys/" + fmt.Sprint(req.KeyID) + "/decrypt",
	}

	err = scwReq.SetBody(req)
	if err != nil {
		return nil, err
	}

	var resp DecryptResponse

	err = s.client.Do(scwReq, &resp, opts...)
	if err != nil {
		return nil, err
	}
	return &resp, nil
}

// Sign: Use a given key to sign a message digest. The key must have its usage set to `asymmetric_signing`. The digest must be created using the same digest algorithm that is defined in the key's algorithm configuration.
func (s *API) Sign(req *SignRequest, opts ...scw.RequestOption) (*SignResponse, error) {
	var err error

	if req.Region == "" {
		defaultRegion, _ := s.client.GetDefaultRegion()
		req.Region = defaultRegion
	}

	if fmt.Sprint(req.Region) == "" {
		return nil, errors.New("field Region cannot be empty in request")
	}

	if fmt.Sprint(req.KeyID) == "" {
		return nil, errors.New("field KeyID cannot be empty in request")
	}

	scwReq := &scw.ScalewayRequest{
		Method: "POST",
		Path:   "/key-manager/v1alpha1/regions/" + fmt.Sprint(req.Region) + "/keys/" + fmt.Sprint(req.KeyID) + "/sign",
	}

	err = scwReq.SetBody(req)
	if err != nil {
		return nil, err
	}

	var resp SignResponse

	err = s.client.Do(scwReq, &resp, opts...)
	if err != nil {
		return nil, err
	}
	return &resp, nil
}

// Verify: Use a given key to verify a message signature against a message digest. The key must have its usage set to `asymmetric_signing`. The message digest must be generated using the same digest algorithm that is defined in the key's algorithm configuration.
func (s *API) Verify(req *VerifyRequest, opts ...scw.RequestOption) (*VerifyResponse, error) {
	var err error

	if req.Region == "" {
		defaultRegion, _ := s.client.GetDefaultRegion()
		req.Region = defaultRegion
	}

	if fmt.Sprint(req.Region) == "" {
		return nil, errors.New("field Region cannot be empty in request")
	}

	if fmt.Sprint(req.KeyID) == "" {
		return nil, errors.New("field KeyID cannot be empty in request")
	}

	scwReq := &scw.ScalewayRequest{
		Method: "POST",
		Path:   "/key-manager/v1alpha1/regions/" + fmt.Sprint(req.Region) + "/keys/" + fmt.Sprint(req.KeyID) + "/verify",
	}

	err = scwReq.SetBody(req)
	if err != nil {
		return nil, err
	}

	var resp VerifyResponse

	err = s.client.Do(scwReq, &resp, opts...)
	if err != nil {
		return nil, err
	}
	return &resp, nil
}

// ImportKeyMaterial: Import externally generated key material into Key Manager to derive a new cryptographic key. The key's origin must be `external`.
func (s *API) ImportKeyMaterial(req *ImportKeyMaterialRequest, opts ...scw.RequestOption) (*Key, error) {
	var err error

	if req.Region == "" {
		defaultRegion, _ := s.client.GetDefaultRegion()
		req.Region = defaultRegion
	}

	if fmt.Sprint(req.Region) == "" {
		return nil, errors.New("field Region cannot be empty in request")
	}

	if fmt.Sprint(req.KeyID) == "" {
		return nil, errors.New("field KeyID cannot be empty in request")
	}

	scwReq := &scw.ScalewayRequest{
		Method: "POST",
		Path:   "/key-manager/v1alpha1/regions/" + fmt.Sprint(req.Region) + "/keys/" + fmt.Sprint(req.KeyID) + "/import-key-material",
	}

	err = scwReq.SetBody(req)
	if err != nil {
		return nil, err
	}

	var resp Key

	err = s.client.Do(scwReq, &resp, opts...)
	if err != nil {
		return nil, err
	}
	// platform := s.client.GetPlatform()
	platform := "scw.eu"
	resp.setSRN(platform)
	return &resp, nil
}

// DeleteKeyMaterial: Delete previously imported key material. This renders the associated cryptographic key unusable for any operation. The key's origin must be `external`.
func (s *API) DeleteKeyMaterial(req *DeleteKeyMaterialRequest, opts ...scw.RequestOption) error {
	var err error

	if req.Region == "" {
		defaultRegion, _ := s.client.GetDefaultRegion()
		req.Region = defaultRegion
	}

	if fmt.Sprint(req.Region) == "" {
		return errors.New("field Region cannot be empty in request")
	}

	if fmt.Sprint(req.KeyID) == "" {
		return errors.New("field KeyID cannot be empty in request")
	}

	scwReq := &scw.ScalewayRequest{
		Method: "POST",
		Path:   "/key-manager/v1alpha1/regions/" + fmt.Sprint(req.Region) + "/keys/" + fmt.Sprint(req.KeyID) + "/delete-key-material",
	}

	err = scwReq.SetBody(req)
	if err != nil {
		return err
	}

	err = s.client.Do(scwReq, nil, opts...)
	if err != nil {
		return err
	}
	return nil
}

// RestoreKey: Restore a key and all its rotations scheduled for deletion specified by the `region` and `key_id` parameters.
func (s *API) RestoreKey(req *RestoreKeyRequest, opts ...scw.RequestOption) (*Key, error) {
	var err error

	if req.Region == "" {
		defaultRegion, _ := s.client.GetDefaultRegion()
		req.Region = defaultRegion
	}

	if fmt.Sprint(req.Region) == "" {
		return nil, errors.New("field Region cannot be empty in request")
	}

	if fmt.Sprint(req.KeyID) == "" {
		return nil, errors.New("field KeyID cannot be empty in request")
	}

	scwReq := &scw.ScalewayRequest{
		Method: "POST",
		Path:   "/key-manager/v1alpha1/regions/" + fmt.Sprint(req.Region) + "/keys/" + fmt.Sprint(req.KeyID) + "/restore",
	}

	err = scwReq.SetBody(req)
	if err != nil {
		return nil, err
	}

	var resp Key

	err = s.client.Do(scwReq, &resp, opts...)
	if err != nil {
		return nil, err
	}
	// platform := s.client.GetPlatform()
	platform := "scw.eu"
	resp.setSRN(platform)
	return &resp, nil
}

// ListAlgorithms: Lists all cryptographic algorithms supported by the Key Manager service.
func (s *API) ListAlgorithms(req *ListAlgorithmsRequest, opts ...scw.RequestOption) (*ListAlgorithmsResponse, error) {
	var err error

	if req.Region == "" {
		defaultRegion, _ := s.client.GetDefaultRegion()
		req.Region = defaultRegion
	}

	query := url.Values{}
	parameter.AddToQuery(query, "usages", req.Usages)

	if fmt.Sprint(req.Region) == "" {
		return nil, errors.New("field Region cannot be empty in request")
	}

	scwReq := &scw.ScalewayRequest{
		Method: "GET",
		Path:   "/key-manager/v1alpha1/regions/" + fmt.Sprint(req.Region) + "/algorithms",
		Query:  query,
	}

	var resp ListAlgorithmsResponse

	err = s.client.Do(scwReq, &resp, opts...)
	if err != nil {
		return nil, err
	}
	return &resp, nil
}
