using System;

namespace Ethanol.DataObjects
{
    /// <summary>
    /// Represents details of a Transport Layer Security (TLS) flow, derived from an IP flow.
    /// This encompasses information related to the TLS handshake, certificate details, and other TLS-specific attributes.
    /// </summary>
    public class TlsFlow : IpFlow
    {
        /// <summary>
        /// Gets or sets the common name (CN) of the certificate issuer.
        /// </summary>
        public string? IssuerCommonName { get; set; }

        /// <summary>
        /// Gets or sets the common name (CN) of the certificate subject.
        /// </summary>
        public string? SubjectCommonName { get; set; }

        /// <summary>
        /// Gets or sets the organizational name of the certificate subject.
        /// </summary>
        public string? SubjectOrganisationName { get; set; }

        /// <summary>
        /// Gets or sets the start date of the certificate's validity period.
        /// </summary>
        public DateTime CertificateValidityFrom { get; set; }

        /// <summary>
        /// Gets or sets the end date of the certificate's validity period.
        /// </summary>
        public DateTime CertificateValidityTo { get; set; }

        /// <summary>
        /// Gets or sets the signature algorithm used in the certificate.
        /// </summary>
        public string? SignatureAlgorithm { get; set; }

        /// <summary>
        /// Gets or sets the public key algorithm used in the certificate.
        /// </summary>
        public string? PublicKeyAlgorithm { get; set; }

        /// <summary>
        /// Gets or sets the length of the public key in the certificate.
        /// </summary>
        public int PublicKeyLength { get; set; }

        /// <summary>
        /// Gets or sets the TLS version used by the client.
        /// </summary>
        public string? ClientVersion { get; set; }

        /// <summary>
        /// Gets or sets the cipher suites proposed by the client.
        /// </summary>
        public string? CipherSuites { get; set; }

        /// <summary>
        /// Gets or sets the random ID generated by the client for the session.
        /// </summary>
        public string? ClientRandomID { get; set; }

        /// <summary>
        /// Gets or sets the session ID proposed by the client.
        /// </summary>
        public string? ClientSessionID { get; set; }

        /// <summary>
        /// Gets or sets the types of extensions proposed by the client.
        /// </summary>
        public ushort[]? ExtensionTypes { get; set; }

        /// <summary>
        /// Gets or sets the lengths of the extensions proposed by the client.
        /// </summary>
        public ushort[]? ExtensionLengths { get; set; }

        /// <summary>
        /// Gets or sets the elliptic curves supported by the client.
        /// </summary>
        public string? EllipticCurves { get; set; }

        /// <summary>
        /// Gets or sets the elliptic curve point formats supported by the client.
        /// </summary>
        public string? EcPointFormats { get; set; }

        /// <summary>
        /// Gets or sets the length of the client's key.
        /// </summary>
        public int ClientKeyLength { get; set; }

        /// <summary>
        /// Gets or sets the JA3 fingerprint of the client, which provides a method for creating fingerprints from TLS client handshakes.
        /// </summary>
        public string? JA3Fingerprint { get; set; }

        /// <summary>
        /// Gets or sets the content type of the TLS message.
        /// </summary>
        public TlsContentType ContentType { get; set; }

        /// <summary>
        /// Gets or sets the type of the TLS handshake message.
        /// </summary>
        public TlsHandshakeType HandshakeType { get; set; }

        /// <summary>
        /// Gets or sets the time taken for the TLS handshake to be established.
        /// </summary>
        public TimeSpan SetupTime { get; set; }

        /// <summary>
        /// Gets or sets the TLS version used by the server.
        /// </summary>
        public string? ServerVersion { get; set; }

        /// <summary>
        /// Gets or sets the random ID generated by the server for the session.
        /// </summary>
        public string? ServerRandomID { get; set; }

        /// <summary>
        /// Gets or sets the session ID proposed by the server.
        /// </summary>
        public string? ServerSessionID { get; set; }

        /// <summary>
        /// Gets or sets the cipher suite chosen by the server.
        /// </summary>
        public string? ServerCipherSuite { get; set; }

        /// <summary>
        /// Gets or sets the application-layer protocol negotiated between the client and server.
        /// </summary>
        public string? ApplicationLayerProtocolNegotiation { get; set; }

        /// <summary>
        /// Gets or sets the server name indication.
        /// </summary>
        public string? ServerNameIndication { get; set; }

        /// <summary>
        /// Gets or sets the server name length.
        /// </summary>
        public int ServerNameLength { get; set; }
    }

    public enum TlsHandshakeType
    {
        HelloRequest = 0,
        ClientHello = 1,
        ServerHello = 2,
        Certificate = 11,
        ServerKeyExchange = 12,
        CertificateRequest = 13,
        ServerHelloDone = 14,
        CertificateVerify = 15,
        ClientKeyExchange = 16,
        Finished = 20
    }

    public enum TlsContentType
    {
        ChangeCipherSpec = 20,
        Alert = 21,
        Handshake = 22,
        ApplicationData = 23,
        Heartbeat = 24
    }
}
