import logging

from cryptography.x509 import load_der_x509_certificate
from OpenSSL.crypto import X509
from webauthn.helpers import parse_attestation_object
from webauthn.helpers.structs import AttestationFormat

from console_webauthn.choices import CredentialFormat

logger = logging.getLogger()


def get_credential_type(fmt: AttestationFormat, attestation: bytes) -> CredentialFormat:
    """
    Inspect attestation and extract the type of device / credential
    from the public key, if possible.
    """
    if fmt == AttestationFormat.PACKED:
        pao = parse_attestation_object(attestation)

        if leaf_cert := get_leaf_certificate_from_x5c(pao.att_stmt.x5c):
            issuer = leaf_cert.get_issuer()
            if 'yubico' in issuer.CN.lower():
                return CredentialFormat.Yubikey
            logger.info('Unable to extract Credential Type from Cert Issuer: %s', issuer)

    try:
        return CredentialFormat(fmt)
    except ValueError:
        return CredentialFormat.NONE


def get_leaf_certificate_from_x5c(x5c: list[bytes]) -> X509 | None:
    """
    Return certification object from the x5c bytes, largely extracted from
    webauthn.helpers.validate_certificate_chain.validate_certificate_chain.
    """
    try:
        leaf_cert_crypto = load_der_x509_certificate(x5c[0])
        return X509().from_cryptography(leaf_cert_crypto)
    except Exception as e:
        logger.exception('Unable to load Credential certificate: %s', e)
        return None
