"""
Centralized validation constants used across the PCILeech firmware generator.

This module provides consistent validation lists that are used in multiple
places throughout the codebase for template context validation, critical
variable tracking, and security checks.
"""

from typing import Dict, Final, List, Tuple

# Required context sections for PCILeech context completeness validation
REQUIRED_CONTEXT_SECTIONS: Final[List[str]] = [
    "device_config",
    "config_space",
    "bar_config",
    "interrupt_config",
]

# Minimal essential identifiers for strict gating
CORE_DEVICE_IDS: Final[List[str]] = ["vendor_id", "device_id"]

# Core device ID fields frequently validated together (no subsystem IDs)
# Keep order stable and reuse wherever possible.
CORE_DEVICE_ID_FIELDS: Final[List[str]] = CORE_DEVICE_IDS + [
    "class_code",
    "revision_id",
]

# Subsystem identifier fields grouped once for reuse
SUBSYSTEM_ID_FIELDS: Final[List[str]] = [
    "subsystem_vendor_id",
    "subsystem_device_id",
]

# Device identification fields that are required for all device configurations
# Preserve the canonical ordering expected by tests and templates.
DEVICE_IDENTIFICATION_FIELDS: Final[List[str]] = (
    CORE_DEVICE_IDS + SUBSYSTEM_ID_FIELDS + ["class_code", "revision_id"]
)

# Critical template context keys that must be present for safe firmware generation
# Built from core IDs to avoid duplication.
CRITICAL_TEMPLATE_CONTEXT_KEYS: Final[List[str]] = CORE_DEVICE_IDS + [
    "device_type",
    "device_class",
    "active_device_config",
    "generation_metadata",
    "board_config",
]

# Sensitive tokens that indicate variables should never have fallbacks
# Built from core device ID fields and additional security-related tokens.
SENSITIVE_TOKENS: Final[Tuple[str, ...]] = tuple(
    CORE_DEVICE_ID_FIELDS
    + [
        "bars",
        "subsys",
        # Common sensitive tokens - avoid exposing these in fallbacks
        "token",
        "secret",
        "password",
        "credential",
        "key",
    ]
)

# Hex widths for device identification fields (characters in hex string)
DEVICE_ID_FIELD_WIDTHS: Final[Dict[str, int]] = {
    "vendor_id": 4,
    "device_id": 4,
    "subsystem_vendor_id": 4,
    "subsystem_device_id": 4,
    "class_code": 6,
    "revision_id": 2,
}

# Board configuration fields that are essential for FPGA targeting
ESSENTIAL_BOARD_CONFIG_FIELDS: Final[List[str]] = [
    "name",
    "fpga_part",
    "fpga_family",
    "pcie_ip_type",
]

# Generation metadata fields required for firmware provenance
REQUIRED_METADATA_FIELDS: Final[List[str]] = [
    "generated_at",
    "generator_version",
    "device_signature",
    "build_timestamp",
]

# Known device types supported by the firmware generator
KNOWN_DEVICE_TYPES: Final[List[str]] = [
    "audio",
    "graphics",
    "media",
    "network",
    "processor",
    "storage",
    "usb",
    "generic",  # Keep generic last as it's the fallback
]

# Device class mappings for PCI class code prefixes (hex string -> device type)
DEVICE_CLASS_MAPPINGS: Final[Dict[str, str]] = {
    "01": "storage",
    "02": "network",
    "03": "display",
    "04": "multimedia",
    "0c": "serial_bus",
}

# Power state transition cycle constants (units: cycles)
# These values should be set according to hardware timing requirements.
# Prefer hardware/profile-driven overrides; these are safe defaults.
D0_TO_D1_CYCLES: Final[int] = 100
D1_TO_D0_CYCLES: Final[int] = 200
D0_TO_D3_CYCLES: Final[int] = 500
D3_TO_D0_CYCLES: Final[int] = 1000

# Mapping for convenient consumption by other modules
POWER_TRANSITION_CYCLES: Final[dict] = {
    "d0_to_d1": D0_TO_D1_CYCLES,
    "d1_to_d0": D1_TO_D0_CYCLES,
    "d0_to_d3": D0_TO_D3_CYCLES,
    "d3_to_d0": D3_TO_D0_CYCLES,
}


def get_power_transition_cycles() -> Dict[str, int]:
    """Return a copy of the default power state transition cycles."""
    return dict(POWER_TRANSITION_CYCLES)


# Default values for common template variables
# These provide safe fallbacks when templates reference non-existent attributes
DEFAULT_COUNTER_WIDTH: Final[int] = 32
DEFAULT_PROCESS_VARIATION: Final[float] = 0.1
DEFAULT_TEMPERATURE_COEFFICIENT: Final[float] = 0.05
DEFAULT_VOLTAGE_VARIATION: Final[float] = 0.03

# Standard header for generated SystemVerilog files
SV_FILE_HEADER: Final[str] = "// Generated PCILeech SystemVerilog Module"

# Standard header for generated hex files
HEX_FILE_HEADER: Final[str] = "// Generated by PCILeech Firmware Generator"

# Standard header for generated TCL files
TCL_FILE_HEADER: Final[str] = "# Generated PCILeech TCL Script"

# Device capability validation error messages
DEVICE_CAPABILITY_ERROR_MESSAGES: Final[Dict[str, str]] = {
    "invalid_msi_vector_count": "Invalid MSI vector count: {msi_vectors}",
    "invalid_msix_vector_count": "Invalid MSI-X vector count: {msix_vectors}",
    "invalid_link_width": "Invalid link width: x{link_width}",
    "invalid_ext_cfg_cap_ptr": "Invalid extended config capability pointer: 0x{ext_cfg_cap_ptr:03X}",
    "invalid_ext_cfg_xp_cap_ptr": "Invalid extended config express capability pointer: 0x{ext_cfg_xp_cap_ptr:03X}",
    "ext_cfg_cap_ptr_alignment": "Extended config capability pointer must be 4-byte aligned: 0x{ext_cfg_cap_ptr:03X}",
    "ext_cfg_xp_cap_ptr_alignment": "Extended config express capability pointer must be 4-byte aligned: 0x{ext_cfg_xp_cap_ptr:03X}",
}
