use pem_crate::{EncodeConfig, LineEnding};

/// Supported encoding schmes
pub enum EncodingScheme {
    /// PKCS#1 encoded key
    PKCS1,
    /// PKCS#8 encoded key
    PKCS8,
}

#[derive(PartialEq)]
pub enum KeyType {
    Public,
    Private,
}

impl EncodingScheme {
    fn tag(self, key_type: KeyType) -> String {
        match self {
            EncodingScheme::PKCS1 if key_type == KeyType::Private => "RSA PRIVATE KEY",
            EncodingScheme::PKCS1 if key_type == KeyType::Public => "RSA PUBLIC KEY",

            EncodingScheme::PKCS8 if key_type == KeyType::Private => "PRIVATE KEY",
            EncodingScheme::PKCS8 if key_type == KeyType::Public => "PUBLIC KEY",

            _ => unreachable!(),
        }
        .to_string()
    }
}

/// Encode a PKCS#1 or PKCS#8 encoded key into the PEM format
pub fn encode(
    scheme: EncodingScheme,
    key_type: KeyType,
    line_ending: LineEnding,
    key: Vec<u8>,
) -> String {
    let pem = pem::Pem {
        tag: scheme.tag(key_type),
        contents: key,
    };
    let config = EncodeConfig { line_ending };

    pem::encode_config(&pem, config)
}
