# radar_data_reader/core/structures/base_structures.py

"""
Contains the fundamental base classes, type aliases, and constants
for all data structure definitions in the application.
"""

import ctypes
from dataclasses import dataclass

# --- Ctypes Base and Type Aliases ---


class CtypesStructureBase(ctypes.Structure):
    """A base class for ctypes.Structure with compact memory layout."""

    _pack_ = 1


c_boolean = ctypes.c_uint32
c_radians_t = ctypes.c_float
c_metres_t = ctypes.c_float
c_metres_per_sec_t = ctypes.c_float
c_timetag_t = ctypes.c_int


# --- Base Block (Python-side Representation, not ctypes) ---


@dataclass
class BaseBlock:
    """Base class for any parsed block of data from the radar file."""

    block_name: str
    block_size_words: int


# --- Global Constants ---

BLOCK_TYPE_MAP = {
    # Legacy Blocks (marker 0x5A5A5A5A)
    1213223748: "DSPHDRIN",
    1431261764: "DSPHDROUT",
    5068115: "SUM",
    1380013383: "GUARD",
    5914948: "DAZ",
    4998468: "DEL",
    1181316173: "MTIFFT",
    892678468: "D1553",
    1397769283: "CDPSTS",
    1095976257: "AESA",  # Generic AESA ID, parser determines subtype
    1397773124: "DSPS",
    # Firmware Blocks (marker 0x7A7A7A7A)
    5265477: "EXP",
    17232: "PC",
    5522756: "DET",
    1413893971: "TIMER",
    1347635524: "SOFT",
    1162692948: "EXTLINK",
    1280463939: "CTRLINK",
    1280596037: "SOFTDFE",
}

SIGNAL_DATA_MARKER = 1313304915


from dataclasses import field
from typing import List, Optional

# Importazione ritardata (lazy import) per evitare import circolari
# Python gestirà queste dipendenze al runtime.
# Queste definizioni sono necessarie per i type hints in DataBatch.
from . import generic_structures as generic_structs
from . import cdpsts_structures as cdpsts_structs
from . import d1553_structures as d1553_structs
from . import ge_header_structures as ge_header_structs


@dataclass
class DataBatch:
    """
    Represents a complete data batch, typically starting with a DspHeaderIn
    and containing various subsequent data blocks.
    """

    batch_id: int
    blocks: List[BaseBlock] = field(default_factory=list)
    cdp_sts_results: Optional[cdpsts_structs.CdpStsBlock] = None
    timer_data: Optional[generic_structs.TimerBlock] = None
    aesa_data: Optional[generic_structs.AesaBlock] = None
    d1553_data: Optional[d1553_structs.D1553Block] = None
    exp_data: Optional[generic_structs.ExpBlock] = None
    pc_data: Optional[generic_structs.PcBlock] = None
    det_data: Optional[generic_structs.DetBlock] = None

    @property
    def main_header(self) -> Optional[ge_header_structs.DspHeaderIn]:
        """Convenience property to access the main DspHeaderIn block."""
        for block in self.blocks:
            if isinstance(block, ge_header_structs.DspHeaderIn):
                return block
        return None
