import dataclasses
import textwrap

from siotls.iana import HandshakeType, SignatureScheme
from siotls.language import SerializableBody
from siotls.utils import try_cast

from . import Handshake


@dataclasses.dataclass(init=False)
class CertificateVerify(Handshake, SerializableBody):
    """
    Certificate Verify handshake as defined in :rfc:`8446#section-4.4.3`.
    Follows :class:`~siotls.contents.handshakes.certificate.Certificate`
    to prove that an endpoint possesses the private key corresponding to
    its certificate or raw public key.
    """

    msg_type = HandshakeType.CERTIFICATE_VERIFY

    _struct = textwrap.dedent("""
        struct {
            SignatureScheme algorithm;
            opaque signature<0..2^16-1>;
        } CertificateVerify;
    """)

    algorithm: SignatureScheme | int
    """ The cryptographic algorithm used to generate the signature. """

    signature: bytes
    """ The opaque data generated by the signature algorithm. """

    def __init__(self, algorithm: SignatureScheme | int, signature: bytes):
        self.algorithm = algorithm
        self.signature = signature

    @classmethod
    def parse_body(cls, stream, **kwargs):  # noqa: ARG003
        algorithm = try_cast(SignatureScheme, stream.read_int(2))
        signature = stream.read_var(2)
        return cls(algorithm, signature)

    def serialize_body(self):
        return b''.join([
            self.algorithm.to_bytes(2, 'big'),
            len(self.signature).to_bytes(2, 'big'),
            self.signature,
        ])
