// Copyright 2024, 2025 New Vector Ltd.
// Copyright 2023, 2024 The Matrix.org Foundation C.I.C.
//
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
// Please see LICENSE files in the repository root for full details.

#![allow(clippy::doc_markdown)]

//! Enums from the "OAuth Parameters" IANA registry
//! See <https://www.iana.org/assignments/jose/jose.xhtml>

// Do not edit this file manually

/// OAuth Access Token Type
///
/// Source: <http://www.iana.org/assignments/oauth-parameters/token-types.csv>
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[non_exhaustive]
pub enum OAuthAccessTokenType {
    /// `Bearer`
    Bearer,

    /// `N_A`
    Na,

    /// `PoP`
    PoP,

    /// `DPoP`
    DPoP,

    /// An unknown value.
    Unknown(String),
}

impl core::fmt::Display for OAuthAccessTokenType {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        match self {
            Self::Bearer => write!(f, "Bearer"),
            Self::Na => write!(f, "N_A"),
            Self::PoP => write!(f, "PoP"),
            Self::DPoP => write!(f, "DPoP"),
            Self::Unknown(value) => write!(f, "{value}"),
        }
    }
}

impl core::str::FromStr for OAuthAccessTokenType {
    type Err = core::convert::Infallible;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "Bearer" => Ok(Self::Bearer),
            "N_A" => Ok(Self::Na),
            "PoP" => Ok(Self::PoP),
            "DPoP" => Ok(Self::DPoP),
            value => Ok(Self::Unknown(value.to_owned())),
        }
    }
}

impl<'de> serde::Deserialize<'de> for OAuthAccessTokenType {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::de::Deserializer<'de>,
    {
        let s = String::deserialize(deserializer)?;
        core::str::FromStr::from_str(&s).map_err(serde::de::Error::custom)
    }
}

impl serde::Serialize for OAuthAccessTokenType {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::ser::Serializer,
    {
        serializer.serialize_str(&self.to_string())
    }
}

impl schemars::JsonSchema for OAuthAccessTokenType {
    fn schema_name() -> String {
        "OAuthAccessTokenType".to_owned()
    }

    fn json_schema(_gen: &mut schemars::r#gen::SchemaGenerator) -> schemars::schema::Schema {
        let enums = vec![
            // ---
            schemars::schema::SchemaObject {
                const_value: Some("Bearer".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                const_value: Some("N_A".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                const_value: Some("PoP".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                const_value: Some("DPoP".into()),
                ..Default::default()
            }
            .into(),
        ];

        let description = r"OAuth Access Token Type";
        schemars::schema::SchemaObject {
            metadata: Some(Box::new(schemars::schema::Metadata {
                description: Some(description.to_owned()),
                ..Default::default()
            })),
            subschemas: Some(Box::new(schemars::schema::SubschemaValidation {
                any_of: Some(enums),
                ..Default::default()
            })),
            ..Default::default()
        }
        .into()
    }
}

/// OAuth Authorization Endpoint Response Type
///
/// Source: <http://www.iana.org/assignments/oauth-parameters/endpoint.csv>
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum OAuthAuthorizationEndpointResponseType {
    /// `code`
    Code,

    /// `code id_token`
    CodeIdToken,

    /// `code id_token token`
    CodeIdTokenToken,

    /// `code token`
    CodeToken,

    /// `id_token`
    IdToken,

    /// `id_token token`
    IdTokenToken,

    /// `none`
    None,

    /// `token`
    Token,
}

impl core::fmt::Display for OAuthAuthorizationEndpointResponseType {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        match self {
            Self::Code => write!(f, "code"),
            Self::CodeIdToken => write!(f, "code id_token"),
            Self::CodeIdTokenToken => write!(f, "code id_token token"),
            Self::CodeToken => write!(f, "code token"),
            Self::IdToken => write!(f, "id_token"),
            Self::IdTokenToken => write!(f, "id_token token"),
            Self::None => write!(f, "none"),
            Self::Token => write!(f, "token"),
        }
    }
}

impl core::str::FromStr for OAuthAuthorizationEndpointResponseType {
    type Err = crate::ParseError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "code" => Ok(Self::Code),
            "code id_token" => Ok(Self::CodeIdToken),
            "code id_token token" => Ok(Self::CodeIdTokenToken),
            "code token" => Ok(Self::CodeToken),
            "id_token" => Ok(Self::IdToken),
            "id_token token" => Ok(Self::IdTokenToken),
            "none" => Ok(Self::None),
            "token" => Ok(Self::Token),
            _ => Err(crate::ParseError::new()),
        }
    }
}

impl<'de> serde::Deserialize<'de> for OAuthAuthorizationEndpointResponseType {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::de::Deserializer<'de>,
    {
        let s = String::deserialize(deserializer)?;
        core::str::FromStr::from_str(&s).map_err(serde::de::Error::custom)
    }
}

impl serde::Serialize for OAuthAuthorizationEndpointResponseType {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::ser::Serializer,
    {
        serializer.serialize_str(&self.to_string())
    }
}

impl schemars::JsonSchema for OAuthAuthorizationEndpointResponseType {
    fn schema_name() -> String {
        "OAuthAuthorizationEndpointResponseType".to_owned()
    }

    fn json_schema(_gen: &mut schemars::r#gen::SchemaGenerator) -> schemars::schema::Schema {
        let enums = vec![
            // ---
            schemars::schema::SchemaObject {
                const_value: Some("code".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                const_value: Some("code id_token".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                const_value: Some("code id_token token".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                const_value: Some("code token".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                const_value: Some("id_token".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                const_value: Some("id_token token".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                const_value: Some("none".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                const_value: Some("token".into()),
                ..Default::default()
            }
            .into(),
        ];

        let description = r"OAuth Authorization Endpoint Response Type";
        schemars::schema::SchemaObject {
            metadata: Some(Box::new(schemars::schema::Metadata {
                description: Some(description.to_owned()),
                ..Default::default()
            })),
            subschemas: Some(Box::new(schemars::schema::SubschemaValidation {
                any_of: Some(enums),
                ..Default::default()
            })),
            ..Default::default()
        }
        .into()
    }
}

/// OAuth Token Type Hint
///
/// Source: <http://www.iana.org/assignments/oauth-parameters/token-type-hint.csv>
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[non_exhaustive]
pub enum OAuthTokenTypeHint {
    /// `access_token`
    AccessToken,

    /// `refresh_token`
    RefreshToken,

    /// `pct`
    Pct,

    /// An unknown value.
    Unknown(String),
}

impl core::fmt::Display for OAuthTokenTypeHint {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        match self {
            Self::AccessToken => write!(f, "access_token"),
            Self::RefreshToken => write!(f, "refresh_token"),
            Self::Pct => write!(f, "pct"),
            Self::Unknown(value) => write!(f, "{value}"),
        }
    }
}

impl core::str::FromStr for OAuthTokenTypeHint {
    type Err = core::convert::Infallible;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "access_token" => Ok(Self::AccessToken),
            "refresh_token" => Ok(Self::RefreshToken),
            "pct" => Ok(Self::Pct),
            value => Ok(Self::Unknown(value.to_owned())),
        }
    }
}

impl<'de> serde::Deserialize<'de> for OAuthTokenTypeHint {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::de::Deserializer<'de>,
    {
        let s = String::deserialize(deserializer)?;
        core::str::FromStr::from_str(&s).map_err(serde::de::Error::custom)
    }
}

impl serde::Serialize for OAuthTokenTypeHint {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::ser::Serializer,
    {
        serializer.serialize_str(&self.to_string())
    }
}

impl schemars::JsonSchema for OAuthTokenTypeHint {
    fn schema_name() -> String {
        "OAuthTokenTypeHint".to_owned()
    }

    fn json_schema(_gen: &mut schemars::r#gen::SchemaGenerator) -> schemars::schema::Schema {
        let enums = vec![
            // ---
            schemars::schema::SchemaObject {
                const_value: Some("access_token".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                const_value: Some("refresh_token".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                const_value: Some("pct".into()),
                ..Default::default()
            }
            .into(),
        ];

        let description = r"OAuth Token Type Hint";
        schemars::schema::SchemaObject {
            metadata: Some(Box::new(schemars::schema::Metadata {
                description: Some(description.to_owned()),
                ..Default::default()
            })),
            subschemas: Some(Box::new(schemars::schema::SubschemaValidation {
                any_of: Some(enums),
                ..Default::default()
            })),
            ..Default::default()
        }
        .into()
    }
}

/// OAuth Token Endpoint Authentication Method
///
/// Source: <http://www.iana.org/assignments/oauth-parameters/token-endpoint-auth-method.csv>
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[non_exhaustive]
pub enum OAuthClientAuthenticationMethod {
    /// `none`
    None,

    /// `client_secret_post`
    ClientSecretPost,

    /// `client_secret_basic`
    ClientSecretBasic,

    /// `client_secret_jwt`
    ClientSecretJwt,

    /// `private_key_jwt`
    PrivateKeyJwt,

    /// `tls_client_auth`
    TlsClientAuth,

    /// `self_signed_tls_client_auth`
    SelfSignedTlsClientAuth,

    /// An unknown value.
    Unknown(String),
}

impl core::fmt::Display for OAuthClientAuthenticationMethod {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        match self {
            Self::None => write!(f, "none"),
            Self::ClientSecretPost => write!(f, "client_secret_post"),
            Self::ClientSecretBasic => write!(f, "client_secret_basic"),
            Self::ClientSecretJwt => write!(f, "client_secret_jwt"),
            Self::PrivateKeyJwt => write!(f, "private_key_jwt"),
            Self::TlsClientAuth => write!(f, "tls_client_auth"),
            Self::SelfSignedTlsClientAuth => write!(f, "self_signed_tls_client_auth"),
            Self::Unknown(value) => write!(f, "{value}"),
        }
    }
}

impl core::str::FromStr for OAuthClientAuthenticationMethod {
    type Err = core::convert::Infallible;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "none" => Ok(Self::None),
            "client_secret_post" => Ok(Self::ClientSecretPost),
            "client_secret_basic" => Ok(Self::ClientSecretBasic),
            "client_secret_jwt" => Ok(Self::ClientSecretJwt),
            "private_key_jwt" => Ok(Self::PrivateKeyJwt),
            "tls_client_auth" => Ok(Self::TlsClientAuth),
            "self_signed_tls_client_auth" => Ok(Self::SelfSignedTlsClientAuth),
            value => Ok(Self::Unknown(value.to_owned())),
        }
    }
}

impl<'de> serde::Deserialize<'de> for OAuthClientAuthenticationMethod {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::de::Deserializer<'de>,
    {
        let s = String::deserialize(deserializer)?;
        core::str::FromStr::from_str(&s).map_err(serde::de::Error::custom)
    }
}

impl serde::Serialize for OAuthClientAuthenticationMethod {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::ser::Serializer,
    {
        serializer.serialize_str(&self.to_string())
    }
}

impl schemars::JsonSchema for OAuthClientAuthenticationMethod {
    fn schema_name() -> String {
        "OAuthClientAuthenticationMethod".to_owned()
    }

    fn json_schema(_gen: &mut schemars::r#gen::SchemaGenerator) -> schemars::schema::Schema {
        let enums = vec![
            // ---
            schemars::schema::SchemaObject {
                const_value: Some("none".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                const_value: Some("client_secret_post".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                const_value: Some("client_secret_basic".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                const_value: Some("client_secret_jwt".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                const_value: Some("private_key_jwt".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                const_value: Some("tls_client_auth".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                const_value: Some("self_signed_tls_client_auth".into()),
                ..Default::default()
            }
            .into(),
        ];

        let description = r"OAuth Token Endpoint Authentication Method";
        schemars::schema::SchemaObject {
            metadata: Some(Box::new(schemars::schema::Metadata {
                description: Some(description.to_owned()),
                ..Default::default()
            })),
            subschemas: Some(Box::new(schemars::schema::SubschemaValidation {
                any_of: Some(enums),
                ..Default::default()
            })),
            ..Default::default()
        }
        .into()
    }
}

/// PKCE Code Challenge Method
///
/// Source: <http://www.iana.org/assignments/oauth-parameters/pkce-code-challenge-method.csv>
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[non_exhaustive]
pub enum PkceCodeChallengeMethod {
    /// `plain`
    Plain,

    /// `S256`
    S256,

    /// An unknown value.
    Unknown(String),
}

impl core::fmt::Display for PkceCodeChallengeMethod {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        match self {
            Self::Plain => write!(f, "plain"),
            Self::S256 => write!(f, "S256"),
            Self::Unknown(value) => write!(f, "{value}"),
        }
    }
}

impl core::str::FromStr for PkceCodeChallengeMethod {
    type Err = core::convert::Infallible;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "plain" => Ok(Self::Plain),
            "S256" => Ok(Self::S256),
            value => Ok(Self::Unknown(value.to_owned())),
        }
    }
}

impl<'de> serde::Deserialize<'de> for PkceCodeChallengeMethod {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::de::Deserializer<'de>,
    {
        let s = String::deserialize(deserializer)?;
        core::str::FromStr::from_str(&s).map_err(serde::de::Error::custom)
    }
}

impl serde::Serialize for PkceCodeChallengeMethod {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::ser::Serializer,
    {
        serializer.serialize_str(&self.to_string())
    }
}

impl schemars::JsonSchema for PkceCodeChallengeMethod {
    fn schema_name() -> String {
        "PkceCodeChallengeMethod".to_owned()
    }

    fn json_schema(_gen: &mut schemars::r#gen::SchemaGenerator) -> schemars::schema::Schema {
        let enums = vec![
            // ---
            schemars::schema::SchemaObject {
                const_value: Some("plain".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                const_value: Some("S256".into()),
                ..Default::default()
            }
            .into(),
        ];

        let description = r"PKCE Code Challenge Method";
        schemars::schema::SchemaObject {
            metadata: Some(Box::new(schemars::schema::Metadata {
                description: Some(description.to_owned()),
                ..Default::default()
            })),
            subschemas: Some(Box::new(schemars::schema::SubschemaValidation {
                any_of: Some(enums),
                ..Default::default()
            })),
            ..Default::default()
        }
        .into()
    }
}
