import re
import zlib
from pathlib import Path

LOG_FILE = Path("pc420_dump.log")
OUT_FILE = Path("pc420-original.bin")

BASE_ADDR = 0x80600000
SIZE = 0x800000
EXPECTED_CRC = 0x5e9bef30

# 匹配 U-Boot md.b 输出行：
# 80600000: 12 34 56 ...    ....
line_re = re.compile(
    r"^\s*([0-9a-fA-F]{8})\s*:\s*((?:[0-9a-fA-F]{2}\s+){1,16})"
)

buf = bytearray([0xFF]) * SIZE
seen = 0
min_addr = None
max_addr = None

with LOG_FILE.open("r", encoding="utf-8", errors="ignore") as f:
    for line in f:
        m = line_re.match(line)
        if not m:
            continue

        addr = int(m.group(1), 16)
        if addr < BASE_ADDR or addr >= BASE_ADDR + SIZE:
            continue

        hex_part = m.group(2).strip().split()
        data = bytes(int(x, 16) for x in hex_part)

        off = addr - BASE_ADDR
        end = off + len(data)

        if end <= SIZE:
            buf[off:end] = data
            seen += len(data)
            min_addr = addr if min_addr is None else min(min_addr, addr)
            max_addr = addr + len(data) - 1 if max_addr is None else max(max_addr, addr + len(data) - 1)

OUT_FILE.write_bytes(buf)

crc = zlib.crc32(buf) & 0xFFFFFFFF

print(f"parsed bytes roughly: {seen}")
print(f"min addr: {hex(min_addr) if min_addr is not None else None}")
print(f"max addr: {hex(max_addr) if max_addr is not None else None}")
print(f"output file: {OUT_FILE}")
print(f"output size: {OUT_FILE.stat().st_size}")
print(f"crc32: {crc:08x}")
print(f"expected crc32: {EXPECTED_CRC:08x}")

if OUT_FILE.stat().st_size != SIZE:
    print("ERROR: output size is wrong")
elif crc != EXPECTED_CRC:
    print("ERROR: CRC mismatch. Dump log may be incomplete or corrupted.")
else:
    print("OK: backup is valid.")