import re
import sys

# -----------------------------
# HDGL Covenant Reconstructor
# -----------------------------

# Path to your covenant file (plain text)
COVENANT_FILE = "hdgl_covenant.txt"
OUTPUT_FILE = "reconstructed_file.bin"

# Optional: Fibonacci delta sequence (matches your covenant)
FIBS = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233]

# -----------------------------
# Helper Functions
# -----------------------------

def parse_covenant_line(line):
    """
    Parse a covenant line and extract vector and param range
    Example line:
    0x477bdc6d7ff401515d0484d006309673 5740232704 5740232705 5740232705 OP_WITHINVERIFY
    """
    tokens = line.strip().split()
    if len(tokens) < 4:
        return None
    try:
        vector = int(tokens[0], 16)
        param_min = int(tokens[1])
        param_max = int(tokens[2])
        return vector, param_min, param_max
    except ValueError:
        return None

def vector_to_bytes(vector, fib_delta):
    """
    Convert vector integer to bytes and apply Fibonacci delta.
    """
    byte_len = (vector.bit_length() + 7) // 8
    chunk = vector.to_bytes(byte_len, 'big')
    # Apply delta
    chunk = bytes((b + fib_delta) % 256 for b in chunk)
    return chunk

# -----------------------------
# Main Reconstruction
# -----------------------------

def reconstruct_file(covenant_file, output_file):
    reconstructed_bytes = bytearray()
    fib_index = 0
    
    with open(covenant_file, "r") as f:
        for line in f:
            if "OP_WITHINVERIFY" not in line:
                continue
            parsed = parse_covenant_line(line)
            if parsed is None:
                continue
            vector, param_min, param_max = parsed
            
            fib_delta = FIBS[fib_index % len(FIBS)]
            fib_index += 1
            
            chunk = vector_to_bytes(vector, fib_delta)
            reconstructed_bytes.extend(chunk)
    
    with open(output_file, "wb") as out:
        out.write(reconstructed_bytes)
    
    print(f"[+] Reconstruction complete: {output_file}")
    print(f"[+] Total bytes: {len(reconstructed_bytes)}")

# -----------------------------
# Execute
# -----------------------------

if __name__ == "__main__":
    covenant_path = sys.argv[1] if len(sys.argv) > 1 else COVENANT_FILE
    output_path = sys.argv[2] if len(sys.argv) > 2 else OUTPUT_FILE
    reconstruct_file(covenant_path, output_path)
