// Code generated by tools/cmd/genjwa/main.go. DO NOT EDIT.

package jwa

import (
	"encoding/json"
	"fmt"

	"github.com/lestrrat-go/jwx/v3/internal/tokens"
)

func init() {
	// builtin values for ContentEncryptionAlgorithm
	algorithms := make([]ContentEncryptionAlgorithm, 6)
	algorithms[0] = NewContentEncryptionAlgorithm(tokens.A128CBC_HS256)
	algorithms[1] = NewContentEncryptionAlgorithm(tokens.A128GCM)
	algorithms[2] = NewContentEncryptionAlgorithm(tokens.A192CBC_HS384)
	algorithms[3] = NewContentEncryptionAlgorithm(tokens.A192GCM)
	algorithms[4] = NewContentEncryptionAlgorithm(tokens.A256CBC_HS512)
	algorithms[5] = NewContentEncryptionAlgorithm(tokens.A256GCM)

	RegisterContentEncryptionAlgorithm(algorithms...)
	for _, alg := range algorithms {
		markBuiltin(alg.String())
	}
}

// A128CBC_HS256 returns an object representing A128CBC-HS256. Using this value specifies that the content should be encrypted using AES-CBC + HMAC-SHA256 (128).
func A128CBC_HS256() ContentEncryptionAlgorithm {
	return lookupBuiltinContentEncryptionAlgorithm(tokens.A128CBC_HS256)
}

// A128GCM returns an object representing A128GCM. Using this value specifies that the content should be encrypted using AES-GCM (128).
func A128GCM() ContentEncryptionAlgorithm {
	return lookupBuiltinContentEncryptionAlgorithm(tokens.A128GCM)
}

// A192CBC_HS384 returns an object representing A192CBC-HS384. Using this value specifies that the content should be encrypted using AES-CBC + HMAC-SHA384 (192).
func A192CBC_HS384() ContentEncryptionAlgorithm {
	return lookupBuiltinContentEncryptionAlgorithm(tokens.A192CBC_HS384)
}

// A192GCM returns an object representing A192GCM. Using this value specifies that the content should be encrypted using AES-GCM (192).
func A192GCM() ContentEncryptionAlgorithm {
	return lookupBuiltinContentEncryptionAlgorithm(tokens.A192GCM)
}

// A256CBC_HS512 returns an object representing A256CBC-HS512. Using this value specifies that the content should be encrypted using AES-CBC + HMAC-SHA512 (256).
func A256CBC_HS512() ContentEncryptionAlgorithm {
	return lookupBuiltinContentEncryptionAlgorithm(tokens.A256CBC_HS512)
}

// A256GCM returns an object representing A256GCM. Using this value specifies that the content should be encrypted using AES-GCM (256).
func A256GCM() ContentEncryptionAlgorithm {
	return lookupBuiltinContentEncryptionAlgorithm(tokens.A256GCM)
}

func lookupBuiltinContentEncryptionAlgorithm(name string) ContentEncryptionAlgorithm {
	v, ok := lookupAlgorithm(algKindContentEncryption, name)
	if !ok {
		panic(fmt.Sprintf(`jwa: ContentEncryptionAlgorithm %q not registered`, name))
	}
	return v.(ContentEncryptionAlgorithm)
}

// ContentEncryptionAlgorithm represents the various encryption algorithms as described in https://tools.ietf.org/html/rfc7518#section-5
type ContentEncryptionAlgorithm struct {
	name       string
	deprecated bool
}

func (s ContentEncryptionAlgorithm) String() string {
	return s.name
}

// IsDeprecated returns true if the ContentEncryptionAlgorithm object is deprecated.
func (s ContentEncryptionAlgorithm) IsDeprecated() bool {
	return s.deprecated
}

// EmptyContentEncryptionAlgorithm returns an empty ContentEncryptionAlgorithm object, used as a zero value.
func EmptyContentEncryptionAlgorithm() ContentEncryptionAlgorithm {
	return ContentEncryptionAlgorithm{}
}

// NewContentEncryptionAlgorithm creates a new ContentEncryptionAlgorithm object with the given name.
func NewContentEncryptionAlgorithm(name string, options ...NewAlgorithmOption) ContentEncryptionAlgorithm {
	var deprecated bool
	for _, option := range options {
		switch option.Ident() {
		case identDeprecated{}:
			if err := option.Value(&deprecated); err != nil {
				panic("jwa.NewContentEncryptionAlgorithm: WithDeprecated option must be a boolean")
			}
		}
	}
	return ContentEncryptionAlgorithm{name: name, deprecated: deprecated}
}

// LookupContentEncryptionAlgorithm returns the ContentEncryptionAlgorithm object for the given name.
func LookupContentEncryptionAlgorithm(name string) (ContentEncryptionAlgorithm, bool) {
	if v, ok := lookupAlgorithm(algKindContentEncryption, name); ok {
		return v.(ContentEncryptionAlgorithm), true
	}
	var zero ContentEncryptionAlgorithm
	return zero, false
}

// RegisterContentEncryptionAlgorithm registers a new ContentEncryptionAlgorithm. The signature value must be immutable
// and safe to be used by multiple goroutines, as it is going to be shared with all other users of this library.
//
// Registration is process-global. Built-in identifiers such as RS256 are
// reserved and cannot be replaced by callers after init has completed; use a
// distinct name for third-party algorithms.
//
// SignatureAlgorithm, KeyEncryptionAlgorithm, and ContentEncryptionAlgorithm
// share a single algorithm-name namespace so that KeyAlgorithmFrom can
// resolve unambiguously. Registering a name that is already registered as a
// different kind is a silent no-op (the first Register* call wins).
func RegisterContentEncryptionAlgorithm(algorithms ...ContentEncryptionAlgorithm) {
	for _, alg := range algorithms {
		registerAlgorithm(algKindContentEncryption, alg)
	}
}

// UnregisterContentEncryptionAlgorithm unregisters a ContentEncryptionAlgorithm from its known database.
// Non-existent entries, as well as built-in algorithms will silently be ignored.
func UnregisterContentEncryptionAlgorithm(algorithms ...ContentEncryptionAlgorithm) {
	for _, alg := range algorithms {
		unregisterAlgorithm(algKindContentEncryption, alg.String())
	}
}

// ContentEncryptionAlgorithms returns a list of all available values for ContentEncryptionAlgorithm.
func ContentEncryptionAlgorithms() []ContentEncryptionAlgorithm {
	raw := listAlgorithmsByKind(algKindContentEncryption)
	out := make([]ContentEncryptionAlgorithm, len(raw))
	for i, alg := range raw {
		out[i] = alg.(ContentEncryptionAlgorithm)
	}
	return out
}

// MarshalJSON serializes the ContentEncryptionAlgorithm object to a JSON string.
func (s ContentEncryptionAlgorithm) MarshalJSON() ([]byte, error) {
	return json.Marshal(s.String())
}

// UnmarshalJSON deserializes the JSON string to a ContentEncryptionAlgorithm object.
func (s *ContentEncryptionAlgorithm) UnmarshalJSON(data []byte) error {
	var name string
	if err := json.Unmarshal(data, &name); err != nil {
		return fmt.Errorf(`failed to unmarshal ContentEncryptionAlgorithm: %w`, err)
	}
	v, ok := LookupContentEncryptionAlgorithm(name)
	if !ok {
		return fmt.Errorf(`unknown ContentEncryptionAlgorithm: %q`, name)
	}
	*s = v
	return nil
}
