import pyopencl as cl
import numpy as np
import gzip
import cpio  # hypothetical minimal cpio parser

# ----------------------------
# 1️⃣ Assume HDGL lattice already initialized
# ----------------------------
# lattice_buf, lattice_mem, KERNEL_OFFSET, INITRAMFS_OFFSET from previous step

# ----------------------------
# 2️⃣ Minimal syscall emulation
# ----------------------------
class HDGLSyscall:
    def __init__(self):
        self.files = {}
        self.next_fd = 3  # 0,1,2 reserved

    def open(self, path, mode):
        fd = self.next_fd
        self.files[fd] = {"path": path, "pos": 0, "mode": mode, "data": b""}
        self.next_fd += 1
        print(f"[Syscall] Opened {path} as fd {fd}")
        return fd

    def read(self, fd, size):
        f = self.files[fd]
        data = f["data"][f["pos"]:f["pos"]+size]
        f["pos"] += len(data)
        return data

    def write(self, fd, data):
        f = self.files[fd]
        f["data"] += data
        f["pos"] += len(data)
        return len(data)

    def exit(self, code):
        print(f"[Syscall] Exit with code {code}")
        raise SystemExit(code)

syscall = HDGLSyscall()

# ----------------------------
# 3️⃣ Initramfs loader
# ----------------------------
def load_initramfs(initramfs_bytes):
    with gzip.GzipFile(fileobj=initramfs_bytes) as gz:
        cpio_data = gz.read()
    archive = cpio.CPIOArchive(cpio_data)
    for file in archive.files:
        syscall.open(file.name, "r").data = file.data
        print(f"[Initramfs] Loaded {file.name} ({len(file.data)} bytes)")

# ----------------------------
# 4️⃣ Minimal /dev, /proc, /sys
# ----------------------------
syscall.open("/dev/null", "rw")
syscall.open("/dev/console", "rw")
syscall.open("/proc/cpuinfo", "r").data = b"HDGL virtual CPU\n"

# ----------------------------
# 5️⃣ Kernel “main loop” emulation
# ----------------------------
def kernel_emulate():
    ip = KERNEL_OFFSET
    ticks = 0
    MAX_TICKS = 5_000_000
    while ticks < MAX_TICKS:
        opcode = lattice_mem[ip]
        if opcode == 0xCD:  # int n
            int_no = lattice_mem[ip+1]
            if int_no == 0x80:
                # minimal syscall: AX determines which syscall
                ax = 1  # pretend always write
                syscall.write(1, b"[HDGL] Syscall write\n")
            ip += 2
        else:
            ip += 1
        ticks += 1
        if ticks % 500_000 == 0:
            print(f"[HDGL] Kernel tick {ticks}")

# ----------------------------
# 6️⃣ Boot Debian inside HDGL
# ----------------------------
print("[HDGL] Booting Debian initramfs inside lattice...")
initramfs_bytes = open("initramfs.cpio.gz", "rb")
load_initramfs(initramfs_bytes)
kernel_emulate()
print("[HDGL] Debian kernel init sequence reached. Minimal OS running in lattice.")
