"""Pure exploit mitigation helpers."""

from __future__ import annotations

from typing import Any

CONTROL_FLOW_GUARD_DESC = "Control Flow Guard (prevents indirect call/jump hijacking)"
DIGITAL_SIGNATURE_DESC = "Authenticode digital signature verification"


def build_dll_characteristics_result(
    dll_characteristics: int,
    known_flags: dict[int, str],
) -> tuple[dict[str, Any], dict[str, Any]]:
    flags_found: dict[str, bool] = {}
    for flag_value, flag_name in known_flags.items():
        if dll_characteristics & flag_value:
            flags_found[flag_name] = True

    details = {
        "value": hex(dll_characteristics),
        "flags": flags_found,
    }
    mitigations = {
        "ASLR": {
            "enabled": "DYNAMIC_BASE" in flags_found,
            "high_entropy": "HIGH_ENTROPY_VA" in flags_found,
            "description": "Address Space Layout Randomization",
        },
        "DEP": {
            "enabled": "NX_COMPAT" in flags_found,
            "description": "Data Execution Prevention (NX bit)",
        },
        "CFG": {
            "enabled": "GUARD_CF" in flags_found,
            "description": CONTROL_FLOW_GUARD_DESC,
        },
        "Force_Integrity": {
            "enabled": "FORCE_INTEGRITY" in flags_found,
            "description": "Force code integrity checks",
        },
        "AppContainer": {
            "enabled": "APPCONTAINER" in flags_found,
            "description": "Runs in AppContainer sandbox",
        },
        "No_SEH": {
            "enabled": "NO_SEH" in flags_found,
            "description": "No Structured Exception Handler",
        },
    }
    return details, mitigations


def build_safe_seh_entry(
    enabled: bool, note: str | None = None, error: str | None = None
) -> dict[str, Any]:
    entry = {
        "enabled": enabled,
        "description": "Safe Structured Exception Handling",
    }
    if note:
        entry["note"] = note
    if error:
        entry["error"] = error
    return entry


def build_stack_cookie_entry(
    enabled: bool, cookie: str | None = None, note: str | None = None
) -> dict[str, Any]:
    entry: dict[str, Any] = {
        "enabled": enabled,
        "description": "Stack buffer overflow protection (GS)",
    }
    if cookie:
        entry["cookie"] = cookie
    if note:
        entry["note"] = note
    return entry


def read_u32(data: list[int], offset: int) -> int:
    return (
        data[offset] | (data[offset + 1] << 8) | (data[offset + 2] << 16) | (data[offset + 3] << 24)
    )


def update_mitigations_from_guard_flags(mitigations: dict[str, Any], guard_flags: int) -> None:
    if guard_flags & 0x100:
        mitigations["CFG"] = {
            "enabled": True,
            "description": CONTROL_FLOW_GUARD_DESC,
            "details": "CF instrumented and enabled",
        }
    if guard_flags & 0x20000:
        mitigations["RFG"] = {
            "enabled": True,
            "description": "Return Flow Guard",
            "details": "RF instrumented" + (" and enabled" if guard_flags & 0x40000 else ""),
        }


def parse_load_config(
    config_data: list[int],
    size: int,
    offset: int,
    is_64bit: bool,
    mitigations: dict[str, Any],
) -> dict[str, Any]:
    load_config: dict[str, Any] = {"present": True, "size": size, "offset": offset}
    if len(config_data) < 92:
        return load_config

    config_size = read_u32(config_data, 0)
    load_config["structure_size"] = config_size

    cookie_offset = 88 if is_64bit else 60
    if len(config_data) >= cookie_offset + 4:
        security_cookie = read_u32(config_data, cookie_offset)
        load_config["security_cookie"] = hex(security_cookie) if security_cookie else None

    if config_size >= 148:
        guard_flags_offset = 144 if is_64bit else 140
        if len(config_data) >= guard_flags_offset + 4:
            guard_flags = read_u32(config_data, guard_flags_offset)
            load_config["guard_flags"] = {
                "value": hex(guard_flags),
                "cf_instrumented": bool(guard_flags & 0x100),
                "cf_function_table_present": bool(guard_flags & 0x200),
                "cf_long_jump_table_present": bool(guard_flags & 0x400),
                "rf_instrumented": bool(guard_flags & 0x20000),
                "rf_enable": bool(guard_flags & 0x40000),
                "rf_strict": bool(guard_flags & 0x80000),
                "retpoline_present": bool(guard_flags & 0x100000),
                "eh_continuation_table_present": bool(guard_flags & 0x400000),
            }
            update_mitigations_from_guard_flags(mitigations, guard_flags)

    return load_config


def build_authenticode_entry(enabled: bool, note: str, size: int | None = None) -> dict[str, Any]:
    entry: dict[str, Any] = {
        "enabled": enabled,
        "description": DIGITAL_SIGNATURE_DESC,
        "note": note,
    }
    if size is not None:
        entry["size"] = size
    return entry


def build_pe_info(optional_header: dict[str, Any], is_dll: bool) -> dict[str, Any] | None:
    subsystem = optional_header.get("subsystem", "")
    if not subsystem:
        return None
    return {
        "subsystem": subsystem,
        "is_dll": is_dll,
        "is_driver": "driver" in subsystem.lower(),
    }


def build_relocations_vulnerability(
    aslr_enabled: bool, characteristics: int
) -> dict[str, Any] | None:
    relocs_stripped = bool(characteristics & 0x0001)
    if relocs_stripped and aslr_enabled:
        return {
            "issue": "ASLR ineffective",
            "description": "Relocations stripped but ASLR enabled - ASLR will not work properly",
            "severity": "high",
        }
    return None


def build_entry_point_vulnerability(entry_in_exec_section: bool) -> dict[str, Any] | None:
    if entry_in_exec_section:
        return None
    return {
        "issue": "Unusual entry point",
        "description": "Entry point not in executable section",
        "severity": "medium",
    }
