"""
This module provides a simple interface for generating RSA key pairs
"""

from cryptography import x509
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.x509.oid import NameOID
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.backends import default_backend


def generate_private_key(key_path: str):
    """Generate a new RSA private key and save it to a file."""

    private_key = rsa.generate_private_key(
        public_exponent=65537,
        key_size=4096,
    )

    pem_private_key = private_key.private_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PrivateFormat.PKCS8,
        encryption_algorithm=serialization.NoEncryption(),
    )

    with open(key_path, "wb") as f:
        f.write(pem_private_key)

    return pem_private_key


# pylint: disable=too-many-arguments,too-many-positional-arguments
def generate_csr_from_private_key(
    private_key_content: bytes,
    country: str,
    state: str,
    locality: str,
    organization: str,
    common_name: str,
) -> str:
    """
    Generate a CSR (Certificate Signing Request) from an existing private key.
    Returns:
        str: The generated CSR in PEM format.
    """

    private_key = serialization.load_pem_private_key(
        private_key_content,
        password=None,
        backend=default_backend(),
    )

    csr_builder = x509.CertificateSigningRequestBuilder()
    csr_builder = csr_builder.subject_name(
        x509.Name(
            [
                x509.NameAttribute(NameOID.COUNTRY_NAME, country),
                x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, state),
                x509.NameAttribute(NameOID.LOCALITY_NAME, locality),
                x509.NameAttribute(NameOID.ORGANIZATION_NAME, organization),
                x509.NameAttribute(NameOID.COMMON_NAME, common_name),
            ]
        )).add_extension(
                x509.BasicConstraints(ca=False, path_length=None),
                critical=False,).add_extension(
                x509.UnrecognizedExtension(
                    x509.ObjectIdentifier("2.16.840.1.113730.1.1"),
                    b"SSL Client, S/MIME",
                ),
                critical=False,).add_extension(
                x509.UnrecognizedExtension(
                    x509.ObjectIdentifier("2.16.840.1.113730.1.13"),
                    b"Generated by OBS/OCD",
                ),
                critical=False,
            ).add_extension(
                x509.KeyUsage(
                    digital_signature=True,
                    crl_sign=False,
                    key_encipherment=True,
                    content_commitment=True,
                    data_encipherment=False,
                    key_agreement=False,
                    key_cert_sign=False,
                    encipher_only=False,
                    decipher_only=False,
                ),
                critical=True,
            ).add_extension(
                x509.ExtendedKeyUsage(
                    [
                        x509.ExtendedKeyUsageOID.CLIENT_AUTH,
                        x509.ExtendedKeyUsageOID.EMAIL_PROTECTION,
                    ]
                ),
                critical=False,
            )

    csr = csr_builder.sign(private_key, hashes.SHA256())
    return csr.public_bytes(serialization.Encoding.PEM).decode("utf-8")
