//! Proof types
use std::str::FromStr;

use thiserror::Error;

// https://www.w3.org/TR/vc-data-integrity/
pub(super) const DATA_INTEGRITY_PROOF: &str = "DataIntegrityProof";

// Similar to https://identity.foundation/JcsEd25519Signature2020/
// - Canonicalization algorithm: JCS
// - Digest algorithm: SHA-256
// - Signature algorithm: RSASSA-PKCS1-v1_5
pub(super) const PROOF_TYPE_JCS_RSA: &str = "MitraJcsRsaSignature2022";

// Similar to EthereumPersonalSignature2021 but with JCS
#[cfg(feature = "eip191")]
pub(super) const PROOF_TYPE_JCS_EIP191: &str = "MitraJcsEip191Signature2022";

// Similar to Ed25519Signature2020
// - Canonicalization algorithm: JCS
// - Digest algorithm: BLAKE2b-512
// - Signature algorithm: EdDSA
#[cfg(feature = "minisign")]
pub(super) const PROOF_TYPE_JCS_BLAKE2_ED25519: &str = "MitraJcsEd25519Signature2022";

// https://www.w3.org/TR/vc-di-eddsa/#eddsa-jcs-2022
// (old name, and a variant without context injection)
pub(super) const CRYPTOSUITE_JCS_EDDSA_LEGACY: &str = "jcs-eddsa-2022";
// (normal variant)
pub(super) const CRYPTOSUITE_JCS_EDDSA: &str = "eddsa-jcs-2022";

/// Integrity proof type
#[derive(Debug, PartialEq)]
pub enum ProofType {
    #[cfg(feature = "eip191")]
    JcsEip191Signature,
    #[cfg(feature = "minisign")]
    JcsBlake2Ed25519Signature,
    #[deprecated]
    JcsRsaSignature,
    #[deprecated]
    JcsEddsaSignature,
    /// `eddsa-jcs-2022` cryptosuite  
    /// <https://www.w3.org/TR/vc-di-eddsa/#eddsa-jcs-2022>
    EddsaJcsSignature,
}

/// Error that may occur when cryptosuite name is parsed
#[derive(Debug, Error)]
#[error("unsupported proof type")]
pub struct UnsupportedProofType;

impl FromStr for ProofType {
    type Err = UnsupportedProofType;

    fn from_str(value: &str) -> Result<Self, Self::Err> {
        let proof_type = match value {
            #[cfg(feature = "eip191")]
            PROOF_TYPE_JCS_EIP191 => Self::JcsEip191Signature,
            #[cfg(feature = "minisign")]
            PROOF_TYPE_JCS_BLAKE2_ED25519 => Self::JcsBlake2Ed25519Signature,
            #[expect(deprecated)]
            PROOF_TYPE_JCS_RSA => Self::JcsRsaSignature,
            _ => return Err(UnsupportedProofType),
        };
        Ok(proof_type)
    }
}

impl ProofType {
    pub fn from_cryptosuite(value: &str) -> Result<Self, UnsupportedProofType> {
        let proof_type = match value {
            #[expect(deprecated)]
            CRYPTOSUITE_JCS_EDDSA_LEGACY => Self::JcsEddsaSignature,
            CRYPTOSUITE_JCS_EDDSA => Self::EddsaJcsSignature,
            _ => return Err(UnsupportedProofType),
        };
        Ok(proof_type)
    }
}
