import os
import re

# ================= CONFIG =================
PARTS_DIR = r"downloads/PC_Pro_2011-07"
OUTPUT_DIR = r"downloads"
# ==========================================

ybegin_re = re.compile(r"size=(\d+)")
name_re   = re.compile(r"name=(.+)")
ypart_re  = re.compile(r"begin=(\d+)\s+end=(\d+)")

parts = []
total_size = None
final_name = None

# --- 1. načti všechny yEnc hlavičky ---
for fname in os.listdir(PARTS_DIR):
    if not fname.endswith(".yEncHeader"):
        continue

    part_id = fname.replace(".yEncHeader", "")
    hdr_path = os.path.join(PARTS_DIR, fname)
    bin_path = os.path.join(PARTS_DIR, f"{part_id}.bin")

    if not os.path.exists(bin_path):
        raise RuntimeError(f"Missing bin file for {fname}")

    with open(hdr_path, "r", encoding="utf-8", errors="replace") as f:
        lines = f.read().splitlines()

    begin = end = None

    for line in lines:
        if line.startswith("=ybegin"):
            if total_size is None:
                m = ybegin_re.search(line)
                if m:
                    total_size = int(m.group(1))
                m = name_re.search(line)
                if m:
                    final_name = m.group(1)

        if line.startswith("=ypart"):
            m = ypart_re.search(line)
            if not m:
                raise RuntimeError(f"Cannot parse ypart in {fname}")
            begin = int(m.group(1))
            end   = int(m.group(2))

    if begin is None or end is None:
        raise RuntimeError(f"Missing begin/end in {fname}")

    parts.append({
        "bin": bin_path,
        "begin": begin,
        "end": end
    })

# --- sanity checks ---
if total_size is None or final_name is None:
    raise RuntimeError("Missing ybegin info (size/name)")

output_path = os.path.join(OUTPUT_DIR, final_name)

print(f"📄 Final file: {output_path}")
print(f"📦 Total size: {total_size} bytes")
print(f"🧩 Parts: {len(parts)}")

# --- 2. alokuj cílový soubor ---
with open(output_path, "wb") as f:
    f.truncate(total_size)

# --- 3. zapiš jednotlivé části na správné offsety ---
with open(output_path, "r+b") as out:
    for p in parts:
        expected_len = p["end"] - p["begin"] + 1

        with open(p["bin"], "rb") as bf:
            data = bf.read()

        if len(data) != expected_len:
            print(
                f"⚠️  Size mismatch in {os.path.basename(p['bin'])}: "
                f"expected {expected_len}, got {len(data)}"
            )

        # kratší data jsou OK (CRC, padding, end-of-part)

        out.seek(p["begin"] - 1)  # yEnc je 1-based
        out.write(data)

print("🎉 DONE – file assembled correctly")
