from __future__ import annotations
from dataclasses import dataclass, field
from typing import Iterable

from ..protocol import constants as C
from ..protocol.constants import (
    cipher_is_3des,
    cipher_is_rc4,
    cipher_is_weak,
    cipher_is_cbc,
    cipher_has_fs,
    cipher_is_aead,
)


@dataclass
class VulnPassiveResult:
    poodle_ssl: bool = False
    freak: bool = False
    drown: bool = False
    logjam_export: bool = False
    sweet32: bool = False
    rc4: bool = False
    beast: bool = False
    lucky13: bool = False
    null_cipher: bool = False
    anon_cipher: bool = False
    export_cipher: bool = False
    secure_renego_supported: bool | None = None
    fallback_scsv_supported: bool | None = None
    issues: list[str] = field(default_factory=list)


def analyze(
    versions_supported: set[int],
    accepted_ciphers_per_version: dict[int, list[int]],
) -> VulnPassiveResult:
    r = VulnPassiveResult()

    # DROWN: any SSLv2 support is a direct DROWN exposure.
    if C.SSL_2_0 in versions_supported:
        r.drown = True

    # POODLE (SSL 3.0): SSL 3.0 supported with any CBC cipher.
    if C.SSL_3_0 in versions_supported:
        ciphers = accepted_ciphers_per_version.get(C.SSL_3_0, [])
        for cid in ciphers:
            name = C.CIPHER_SUITES.get(cid, "")
            if cipher_is_cbc(name):
                r.poodle_ssl = True
                break

    # BEAST (TLS 1.0): TLS 1.0 supported with CBC ciphers.
    if C.TLS_1_0 in versions_supported:
        ciphers = accepted_ciphers_per_version.get(C.TLS_1_0, [])
        for cid in ciphers:
            name = C.CIPHER_SUITES.get(cid, "")
            if cipher_is_cbc(name):
                r.beast = True
                break

    # Sweep all ciphers across all versions for cipher-family flags.
    for ver, cids in accepted_ciphers_per_version.items():
        for cid in cids:
            name = C.CIPHER_SUITES.get(cid, "")
            if not name:
                continue
            if cipher_is_3des(name):
                r.sweet32 = True
            if cipher_is_rc4(name):
                r.rc4 = True
            if "NULL" in name:
                r.null_cipher = True
            if "anon" in name:
                r.anon_cipher = True
            if "EXPORT" in name:
                r.export_cipher = True
                r.freak = True
                if "DHE" in name:
                    r.logjam_export = True
            if cipher_is_cbc(name) and ver in (C.TLS_1_0, C.TLS_1_1, C.TLS_1_2):
                r.lucky13 = True
    return r
