import struct
from pathlib import Path

from util import options

from segtypes.gc.segment import GCSegment


class GcSegBi2(GCSegment):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

    def split(self, bi2_bytes):
        lines = []

        # Gathering variables
        debug_monitor_size = struct.unpack_from(">I", bi2_bytes, 0x00)[0]
        simulated_memory_size = struct.unpack_from(">I", bi2_bytes, 0x04)[0]

        argument_offset = struct.unpack_from(">I", bi2_bytes, 0x08)[0]

        debug_flag = struct.unpack_from(">I", bi2_bytes, 0x0C)[0]

        track_offset = struct.unpack_from(">I", bi2_bytes, 0x10)[0]
        track_size = struct.unpack_from(">I", bi2_bytes, 0x14)[0]

        country_code_bi2 = struct.unpack_from(">I", bi2_bytes, 0x18)[0]

        unk_int = struct.unpack_from(">I", bi2_bytes, 0x1C)[0]
        unk_int_2 = struct.unpack_from(">I", bi2_bytes, 0x20)[0]

        # Outputting .s file
        lines.append(f"# GameCube disc image bi2 data, located at 0x440 in the disc.\n")
        lines.append(f"# Generated by splat.\n\n")

        lines.append(f".section .data\n\n")

        lines.append(f"debug_monitor_size: .long 0x{debug_monitor_size:08X}\n")
        lines.append(f"simulated_memory_size: .long 0x{simulated_memory_size:08X}\n\n")

        lines.append(f"argument_offset: .long 0x{argument_offset:08X}\n\n")

        lines.append(f"debug_flag: .long 0x{debug_flag:08X}\n\n")

        lines.append(f"track_offset: .long 0x{track_offset:08X}\n")
        lines.append(f"track_size: .long 0x{track_size:08X}\n\n")

        lines.append(f"country_code_bi2: .long 0x{country_code_bi2:08X}\n\n")

        lines.append(f"ukn_int_bi2: .long 0x{unk_int:08X}\n")
        lines.append(f"ukn_int_bi2_2: .long 0x{unk_int_2:08X}\n\n")

        lines.append(f".fill 0x00001FDC\n\n")

        out_path = self.out_path()
        out_path.parent.mkdir(parents=True, exist_ok=True)

        with open(out_path, "w", encoding="utf-8") as f:
            f.writelines(lines)

        return

    def should_split(self) -> bool:
        return True

    def out_path(self) -> Path:
        return options.opts.asm_path / "sys" / "bi2.s"
