from typing import Optional

from .data import CommonSegData
from ...util import log

from ...disassembler.disassembler_section import (
    DisassemblerSection,
    make_gcc_except_table_section,
)


class CommonSegGcc_except_table(CommonSegData):
    """Segment containing the GCC Except Table (aka ehtable), used for implementing C++ exceptions"""

    def get_linker_section(self) -> str:
        return ".gcc_except_table"

    def get_section_flags(self) -> Optional[str]:
        return "aw"

    def configure_disassembler_section(
        self, disassembler_section: DisassemblerSection
    ) -> None:
        "Allows to configure the section before running the analysis on it"

        super().configure_disassembler_section(disassembler_section)

        section = disassembler_section.get_section()

        section.enableStringGuessing = False

    def disassemble_data(self, rom_bytes):
        if self.is_auto_segment:
            return

        if not isinstance(self.rom_start, int):
            log.error(
                f"Segment '{self.name}' (type '{self.type}') requires a rom_start. Got '{self.rom_start}'"
            )

        # Supposedly logic error, not user error
        assert isinstance(self.rom_end, int), self.rom_end

        # Supposedly logic error, not user error
        segment_rom_start = self.get_most_parent().rom_start
        assert isinstance(segment_rom_start, int), segment_rom_start

        if not isinstance(self.vram_start, int):
            log.error(
                f"Segment '{self.name}' (type '{self.type}') requires a vram address. Got '{self.vram_start}'"
            )

        self.spim_section = make_gcc_except_table_section(
            self.rom_start,
            self.rom_end,
            self.vram_start,
            self.name,
            rom_bytes,
            segment_rom_start,
            self.get_exclusive_ram_id(),
        )

        assert self.spim_section is not None

        self.configure_disassembler_section(self.spim_section)

        self.spim_section.analyze()
        self.spim_section.set_comment_offset(self.rom_start)
