// Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT.

package x509limbo

import "encoding/json"
import "errors"
import "fmt"
import "reflect"
import "regexp"
import "time"

type ExpectedResult string

const ExpectedResultFAILURE ExpectedResult = "FAILURE"
const ExpectedResultSUCCESS ExpectedResult = "SUCCESS"

var enumValues_ExpectedResult = []interface{}{
	"SUCCESS",
	"FAILURE",
}

// UnmarshalJSON implements json.Unmarshaler.
func (j *ExpectedResult) UnmarshalJSON(value []byte) error {
	var v string
	if err := json.Unmarshal(value, &v); err != nil {
		return err
	}
	var ok bool
	for _, expected := range enumValues_ExpectedResult {
		if reflect.DeepEqual(v, expected) {
			ok = true
			break
		}
	}
	if !ok {
		return fmt.Errorf("invalid value (expected one of %#v): %#v", enumValues_ExpectedResult, v)
	}
	*j = ExpectedResult(v)
	return nil
}

type Feature string

const FeatureDenialOfService Feature = "denial-of-service"
const FeatureHasCertPolicies Feature = "has-cert-policies"
const FeatureHasCrl Feature = "has-crl"
const FeatureHasPolicyConstraints Feature = "has-policy-constraints"
const FeatureMaxChainDepth Feature = "max-chain-depth"
const FeatureNameConstraintDn Feature = "name-constraint-dn"
const FeatureNoCertPolicies Feature = "no-cert-policies"
const FeaturePedanticPublicSuffixWildcard Feature = "pedantic-public-suffix-wildcard"
const FeaturePedanticRfc5280 Feature = "pedantic-rfc5280"
const FeaturePedanticSerialNumber Feature = "pedantic-serial-number"
const FeaturePedanticWebpkiEku Feature = "pedantic-webpki-eku"
const FeaturePedanticWebpkiSubscriberKey Feature = "pedantic-webpki-subscriber-key"
const FeatureRfc5280IncompatibleWithWebpki Feature = "rfc5280-incompatible-with-webpki"

var enumValues_Feature = []interface{}{
	"has-policy-constraints",
	"has-cert-policies",
	"no-cert-policies",
	"pedantic-public-suffix-wildcard",
	"name-constraint-dn",
	"pedantic-webpki-subscriber-key",
	"pedantic-webpki-eku",
	"pedantic-serial-number",
	"max-chain-depth",
	"pedantic-rfc5280",
	"rfc5280-incompatible-with-webpki",
	"denial-of-service",
	"has-crl",
}

// UnmarshalJSON implements json.Unmarshaler.
func (j *Feature) UnmarshalJSON(value []byte) error {
	var v string
	if err := json.Unmarshal(value, &v); err != nil {
		return err
	}
	var ok bool
	for _, expected := range enumValues_Feature {
		if reflect.DeepEqual(v, expected) {
			ok = true
			break
		}
	}
	if !ok {
		return fmt.Errorf("invalid value (expected one of %#v): %#v", enumValues_Feature, v)
	}
	*j = Feature(v)
	return nil
}

type Importance string

const ImportanceCritical Importance = "critical"
const ImportanceHigh Importance = "high"
const ImportanceLow Importance = "low"
const ImportanceMedium Importance = "medium"
const ImportanceUndetermined Importance = "undetermined"

var enumValues_Importance = []interface{}{
	"undetermined",
	"low",
	"medium",
	"high",
	"critical",
}

// UnmarshalJSON implements json.Unmarshaler.
func (j *Importance) UnmarshalJSON(value []byte) error {
	var v string
	if err := json.Unmarshal(value, &v); err != nil {
		return err
	}
	var ok bool
	for _, expected := range enumValues_Importance {
		if reflect.DeepEqual(v, expected) {
			ok = true
			break
		}
	}
	if !ok {
		return fmt.Errorf("invalid value (expected one of %#v): %#v", enumValues_Importance, v)
	}
	*j = Importance(v)
	return nil
}

type KeyUsage string

const KeyUsageCRLSign KeyUsage = "cRLSign"
const KeyUsageContentCommitment KeyUsage = "contentCommitment"
const KeyUsageDataEncipherment KeyUsage = "dataEncipherment"
const KeyUsageDecipherOnly KeyUsage = "decipherOnly"
const KeyUsageDigitalSignature KeyUsage = "digitalSignature"
const KeyUsageEncipherOnly KeyUsage = "encipherOnly"
const KeyUsageKeyAgreement KeyUsage = "keyAgreement"
const KeyUsageKeyCertSign KeyUsage = "keyCertSign"
const KeyUsageKeyEncipherment KeyUsage = "keyEncipherment"

var enumValues_KeyUsage = []interface{}{
	"digitalSignature",
	"contentCommitment",
	"keyEncipherment",
	"dataEncipherment",
	"keyAgreement",
	"keyCertSign",
	"cRLSign",
	"encipherOnly",
	"decipherOnly",
}

// UnmarshalJSON implements json.Unmarshaler.
func (j *KeyUsage) UnmarshalJSON(value []byte) error {
	var v string
	if err := json.Unmarshal(value, &v); err != nil {
		return err
	}
	var ok bool
	for _, expected := range enumValues_KeyUsage {
		if reflect.DeepEqual(v, expected) {
			ok = true
			break
		}
	}
	if !ok {
		return fmt.Errorf("invalid value (expected one of %#v): %#v", enumValues_KeyUsage, v)
	}
	*j = KeyUsage(v)
	return nil
}

type KnownEKUs string

const KnownEKUsAnyExtendedKeyUsage KnownEKUs = "anyExtendedKeyUsage"
const KnownEKUsClientAuth KnownEKUs = "clientAuth"
const KnownEKUsCodeSigning KnownEKUs = "codeSigning"
const KnownEKUsEmailProtection KnownEKUs = "emailProtection"
const KnownEKUsOCSPSigning KnownEKUs = "OCSPSigning"
const KnownEKUsServerAuth KnownEKUs = "serverAuth"
const KnownEKUsTimeStamping KnownEKUs = "timeStamping"

var enumValues_KnownEKUs = []interface{}{
	"anyExtendedKeyUsage",
	"serverAuth",
	"clientAuth",
	"codeSigning",
	"emailProtection",
	"timeStamping",
	"OCSPSigning",
}

// UnmarshalJSON implements json.Unmarshaler.
func (j *KnownEKUs) UnmarshalJSON(value []byte) error {
	var v string
	if err := json.Unmarshal(value, &v); err != nil {
		return err
	}
	var ok bool
	for _, expected := range enumValues_KnownEKUs {
		if reflect.DeepEqual(v, expected) {
			ok = true
			break
		}
	}
	if !ok {
		return fmt.Errorf("invalid value (expected one of %#v): %#v", enumValues_KnownEKUs, v)
	}
	*j = KnownEKUs(v)
	return nil
}

// The top-level testcase container.
type Limbo struct {
	// One or more testcases in this testsuite
	Testcases []Testcase `json:"testcases"`

	// The limbo schema version; this must currently always be 1
	Version int `json:"version"`
}

// UnmarshalJSON implements json.Unmarshaler.
func (j *Limbo) UnmarshalJSON(value []byte) error {
	var raw map[string]interface{}
	if err := json.Unmarshal(value, &raw); err != nil {
		return err
	}
	if _, ok := raw["testcases"]; raw != nil && !ok {
		return fmt.Errorf("field testcases in Limbo: required")
	}
	if _, ok := raw["version"]; raw != nil && !ok {
		return fmt.Errorf("field version in Limbo: required")
	}
	type Plain Limbo
	var plain Plain
	if err := json.Unmarshal(value, &plain); err != nil {
		return err
	}
	if plain.Version != 1 {
		return fmt.Errorf("field %s: must be equal to %v", "version", 1)
	}
	*j = Limbo(plain)
	return nil
}

type PeerKind string

const PeerKindDNS PeerKind = "DNS"
const PeerKindIP PeerKind = "IP"
const PeerKindRFC822 PeerKind = "RFC822"

var enumValues_PeerKind = []interface{}{
	"RFC822",
	"DNS",
	"IP",
}

// UnmarshalJSON implements json.Unmarshaler.
func (j *PeerKind) UnmarshalJSON(value []byte) error {
	var v string
	if err := json.Unmarshal(value, &v); err != nil {
		return err
	}
	var ok bool
	for _, expected := range enumValues_PeerKind {
		if reflect.DeepEqual(v, expected) {
			ok = true
			break
		}
	}
	if !ok {
		return fmt.Errorf("invalid value (expected one of %#v): %#v", enumValues_PeerKind, v)
	}
	*j = PeerKind(v)
	return nil
}

// Represents a peer (i.e., end entity) certificate's name (Subject or SAN).
type PeerName struct {
	// The kind of peer name
	Kind PeerKind `json:"kind"`

	// The peer's name
	Value string `json:"value"`
}

// UnmarshalJSON implements json.Unmarshaler.
func (j *PeerName) UnmarshalJSON(value []byte) error {
	var raw map[string]interface{}
	if err := json.Unmarshal(value, &raw); err != nil {
		return err
	}
	if _, ok := raw["kind"]; raw != nil && !ok {
		return fmt.Errorf("field kind in PeerName: required")
	}
	if _, ok := raw["value"]; raw != nil && !ok {
		return fmt.Errorf("field value in PeerName: required")
	}
	type Plain PeerName
	var plain Plain
	if err := json.Unmarshal(value, &plain); err != nil {
		return err
	}
	*j = PeerName(plain)
	return nil
}

type SignatureAlgorithm string

const SignatureAlgorithmDSAWITHSHA1 SignatureAlgorithm = "DSA_WITH_SHA1"
const SignatureAlgorithmDSAWITHSHA224 SignatureAlgorithm = "DSA_WITH_SHA224"
const SignatureAlgorithmDSAWITHSHA256 SignatureAlgorithm = "DSA_WITH_SHA256"
const SignatureAlgorithmDSAWITHSHA384 SignatureAlgorithm = "DSA_WITH_SHA384"
const SignatureAlgorithmDSAWITHSHA512 SignatureAlgorithm = "DSA_WITH_SHA512"
const SignatureAlgorithmECDSAWITHSHA1 SignatureAlgorithm = "ECDSA_WITH_SHA1"
const SignatureAlgorithmECDSAWITHSHA224 SignatureAlgorithm = "ECDSA_WITH_SHA224"
const SignatureAlgorithmECDSAWITHSHA256 SignatureAlgorithm = "ECDSA_WITH_SHA256"
const SignatureAlgorithmECDSAWITHSHA3224 SignatureAlgorithm = "ECDSA_WITH_SHA3_224"
const SignatureAlgorithmECDSAWITHSHA3256 SignatureAlgorithm = "ECDSA_WITH_SHA3_256"
const SignatureAlgorithmECDSAWITHSHA3384 SignatureAlgorithm = "ECDSA_WITH_SHA3_384"
const SignatureAlgorithmECDSAWITHSHA3512 SignatureAlgorithm = "ECDSA_WITH_SHA3_512"
const SignatureAlgorithmECDSAWITHSHA384 SignatureAlgorithm = "ECDSA_WITH_SHA384"
const SignatureAlgorithmECDSAWITHSHA512 SignatureAlgorithm = "ECDSA_WITH_SHA512"
const SignatureAlgorithmED25519 SignatureAlgorithm = "ED25519"
const SignatureAlgorithmED448 SignatureAlgorithm = "ED448"
const SignatureAlgorithmGOSTR34102012WITH34112012256 SignatureAlgorithm = "GOSTR3410_2012_WITH_3411_2012_256"
const SignatureAlgorithmGOSTR34102012WITH34112012512 SignatureAlgorithm = "GOSTR3410_2012_WITH_3411_2012_512"
const SignatureAlgorithmGOSTR341194WITH34102001 SignatureAlgorithm = "GOSTR3411_94_WITH_3410_2001"
const SignatureAlgorithmRSASSAPSS SignatureAlgorithm = "RSASSA_PSS"
const SignatureAlgorithmRSAWITHMD5 SignatureAlgorithm = "RSA_WITH_MD5"
const SignatureAlgorithmRSAWITHSHA1 SignatureAlgorithm = "RSA_WITH_SHA1"
const SignatureAlgorithmRSAWITHSHA224 SignatureAlgorithm = "RSA_WITH_SHA224"
const SignatureAlgorithmRSAWITHSHA256 SignatureAlgorithm = "RSA_WITH_SHA256"
const SignatureAlgorithmRSAWITHSHA3224 SignatureAlgorithm = "RSA_WITH_SHA3_224"
const SignatureAlgorithmRSAWITHSHA3256 SignatureAlgorithm = "RSA_WITH_SHA3_256"
const SignatureAlgorithmRSAWITHSHA3384 SignatureAlgorithm = "RSA_WITH_SHA3_384"
const SignatureAlgorithmRSAWITHSHA3512 SignatureAlgorithm = "RSA_WITH_SHA3_512"
const SignatureAlgorithmRSAWITHSHA384 SignatureAlgorithm = "RSA_WITH_SHA384"
const SignatureAlgorithmRSAWITHSHA512 SignatureAlgorithm = "RSA_WITH_SHA512"

var enumValues_SignatureAlgorithm = []interface{}{
	"RSA_WITH_MD5",
	"RSA_WITH_SHA1",
	"RSA_WITH_SHA224",
	"RSA_WITH_SHA256",
	"RSA_WITH_SHA384",
	"RSA_WITH_SHA512",
	"RSA_WITH_SHA3_224",
	"RSA_WITH_SHA3_256",
	"RSA_WITH_SHA3_384",
	"RSA_WITH_SHA3_512",
	"RSASSA_PSS",
	"ECDSA_WITH_SHA1",
	"ECDSA_WITH_SHA224",
	"ECDSA_WITH_SHA256",
	"ECDSA_WITH_SHA384",
	"ECDSA_WITH_SHA512",
	"ECDSA_WITH_SHA3_224",
	"ECDSA_WITH_SHA3_256",
	"ECDSA_WITH_SHA3_384",
	"ECDSA_WITH_SHA3_512",
	"DSA_WITH_SHA1",
	"DSA_WITH_SHA224",
	"DSA_WITH_SHA256",
	"DSA_WITH_SHA384",
	"DSA_WITH_SHA512",
	"ED25519",
	"ED448",
	"GOSTR3411_94_WITH_3410_2001",
	"GOSTR3410_2012_WITH_3411_2012_256",
	"GOSTR3410_2012_WITH_3411_2012_512",
}

// UnmarshalJSON implements json.Unmarshaler.
func (j *SignatureAlgorithm) UnmarshalJSON(value []byte) error {
	var v string
	if err := json.Unmarshal(value, &v); err != nil {
		return err
	}
	var ok bool
	for _, expected := range enumValues_SignatureAlgorithm {
		if reflect.DeepEqual(v, expected) {
			ok = true
			break
		}
	}
	if !ok {
		return fmt.Errorf("invalid value (expected one of %#v): %#v", enumValues_SignatureAlgorithm, v)
	}
	*j = SignatureAlgorithm(v)
	return nil
}

// Represents an individual Limbo testcase.
type Testcase struct {
	// A list of testcase IDs that this testcase is mutually incompatible with
	ConflictsWith []string `json:"conflicts_with,omitempty,omitzero"`

	// A list of PEM-encoded Certificate Revocation Lists (CRLs)
	Crls []string `json:"crls,omitempty,omitzero"`

	// A short, Markdown-formatted description
	Description string `json:"description"`

	// For server (i.e. client-side) validation: the expected peer name, if any
	ExpectedPeerName *TestcaseExpectedPeerName `json:"expected_peer_name,omitempty,omitzero"`

	// For client (i.e. server-side) validation: the expected peer names
	ExpectedPeerNames []PeerName `json:"expected_peer_names"`

	// The expected validation result
	ExpectedResult ExpectedResult `json:"expected_result"`

	// A constraining list of extended key usages, either in well-known form or as
	// OIDs
	ExtendedKeyUsage []KnownEKUs `json:"extended_key_usage"`

	// Zero or more human-readable tags that describe OPTIONAL functionality described
	// by this testcase. Implementers should use this to specify testcases for
	// non-mandatory X.509 behavior (like certificate policy validation) or for
	// 'pedantic' cases. Consumers that don't understand a given feature should skip
	// tests that are marked with it.
	Features []Feature `json:"features,omitempty,omitzero"`

	// A short, unique identifier for this testcase
	Id string `json:"id"`

	// The testcase's importance
	Importance Importance `json:"importance,omitempty,omitzero"`

	// A constraining list of key usages
	KeyUsage []KeyUsage `json:"key_usage"`

	// The maximum chain-building depth
	MaxChainDepth interface{} `json:"max_chain_depth,omitempty,omitzero"`

	// The PEM-encoded peer (EE) certificate
	PeerCertificate string `json:"peer_certificate"`

	// The PEM-encoded private key for the peer certificate, if present
	PeerCertificateKey interface{} `json:"peer_certificate_key,omitempty,omitzero"`

	// A list of acceptable signature algorithms to constrain against
	SignatureAlgorithms []SignatureAlgorithm `json:"signature_algorithms"`

	// A list of PEM-encoded CA certificates to consider trusted
	TrustedCerts []string `json:"trusted_certs"`

	// A list of PEM-encoded untrusted intermediates to use during path building
	UntrustedIntermediates []string `json:"untrusted_intermediates"`

	// The kind of validation to perform
	ValidationKind ValidationKind `json:"validation_kind"`

	// The time at which to perform the validation
	ValidationTime interface{} `json:"validation_time,omitempty,omitzero"`
}

// For server (i.e. client-side) validation: the expected peer name, if any
type TestcaseExpectedPeerName struct {
	// The kind of peer name
	Kind PeerKind `json:"kind"`

	// The peer's name
	Value string `json:"value"`
}

// UnmarshalJSON implements json.Unmarshaler.
func (j *TestcaseExpectedPeerName) UnmarshalJSON(value []byte) error {
	var raw map[string]interface{}
	if err := json.Unmarshal(value, &raw); err != nil {
		return err
	}
	var testcaseExpectedPeerName_0 TestcaseExpectedPeerName_0
	var errs []error
	if err := testcaseExpectedPeerName_0.UnmarshalJSON(value); err != nil {
		errs = append(errs, err)
	}
	if len(errs) == 1 {
		return fmt.Errorf("all validators failed: %s", errors.Join(errs...))
	}
	type Plain TestcaseExpectedPeerName
	var plain Plain
	if err := json.Unmarshal(value, &plain); err != nil {
		return err
	}
	*j = TestcaseExpectedPeerName(plain)
	return nil
}

type TestcaseMaxChainDepth_0 *int

type TestcasePeerCertificateKey_0 *string

type TestcaseValidationTime_0 *time.Time

// UnmarshalJSON implements json.Unmarshaler.
func (j *Testcase) UnmarshalJSON(value []byte) error {
	var raw map[string]interface{}
	if err := json.Unmarshal(value, &raw); err != nil {
		return err
	}
	if _, ok := raw["description"]; raw != nil && !ok {
		return fmt.Errorf("field description in Testcase: required")
	}
	if _, ok := raw["expected_peer_names"]; raw != nil && !ok {
		return fmt.Errorf("field expected_peer_names in Testcase: required")
	}
	if _, ok := raw["expected_result"]; raw != nil && !ok {
		return fmt.Errorf("field expected_result in Testcase: required")
	}
	if _, ok := raw["extended_key_usage"]; raw != nil && !ok {
		return fmt.Errorf("field extended_key_usage in Testcase: required")
	}
	if _, ok := raw["id"]; raw != nil && !ok {
		return fmt.Errorf("field id in Testcase: required")
	}
	if _, ok := raw["key_usage"]; raw != nil && !ok {
		return fmt.Errorf("field key_usage in Testcase: required")
	}
	if _, ok := raw["peer_certificate"]; raw != nil && !ok {
		return fmt.Errorf("field peer_certificate in Testcase: required")
	}
	if _, ok := raw["signature_algorithms"]; raw != nil && !ok {
		return fmt.Errorf("field signature_algorithms in Testcase: required")
	}
	if _, ok := raw["trusted_certs"]; raw != nil && !ok {
		return fmt.Errorf("field trusted_certs in Testcase: required")
	}
	if _, ok := raw["untrusted_intermediates"]; raw != nil && !ok {
		return fmt.Errorf("field untrusted_intermediates in Testcase: required")
	}
	if _, ok := raw["validation_kind"]; raw != nil && !ok {
		return fmt.Errorf("field validation_kind in Testcase: required")
	}
	type Plain Testcase
	var plain Plain
	if err := json.Unmarshal(value, &plain); err != nil {
		return err
	}
	if v, ok := raw["conflicts_with"]; !ok || v == nil {
		plain.ConflictsWith = []string{}
	}
	if v, ok := raw["crls"]; !ok || v == nil {
		plain.Crls = []string{}
	}
	if v, ok := raw["features"]; !ok || v == nil {
		plain.Features = []Feature{}
	}
	if matched, _ := regexp.MatchString(`^([A-Za-z][A-Za-z0-9-.]+::)*([A-Za-z][A-Za-z0-9-.]+)$`, string(plain.Id)); !matched {
		return fmt.Errorf("field %s pattern match: must match %s", "Id", `^([A-Za-z][A-Za-z0-9-.]+::)*([A-Za-z][A-Za-z0-9-.]+)$`)
	}
	if v, ok := raw["importance"]; !ok || v == nil {
		plain.Importance = "undetermined"
	}
	*j = Testcase(plain)
	return nil
}

type ValidationKind string

const ValidationKindCLIENT ValidationKind = "CLIENT"
const ValidationKindSERVER ValidationKind = "SERVER"

var enumValues_ValidationKind = []interface{}{
	"CLIENT",
	"SERVER",
}

// UnmarshalJSON implements json.Unmarshaler.
func (j *ValidationKind) UnmarshalJSON(value []byte) error {
	var v string
	if err := json.Unmarshal(value, &v); err != nil {
		return err
	}
	var ok bool
	for _, expected := range enumValues_ValidationKind {
		if reflect.DeepEqual(v, expected) {
			ok = true
			break
		}
	}
	if !ok {
		return fmt.Errorf("invalid value (expected one of %#v): %#v", enumValues_ValidationKind, v)
	}
	*j = ValidationKind(v)
	return nil
}

type TestcaseExpectedPeerName_0 = PeerName
