#!/usr/bin/env python3
"""Read-only comparison for the October 27, 2026 Mint compatibility test.

Usage: python3 verify-codex-preservation.py BEFORE AFTER --mode image-content
       python3 verify-codex-preservation.py BEFORE.jsonl.zst AFTER.jsonl.zst --mode decoded-bytes

Requires Pillow for image-content and the zstd command for .zst inputs.
Reads only; does not run Mint, Codex, a model or any cleanup operation.
Image-content compares every non-image byte plus image dimensions, RGBA pixels
and ICC profile. It is not an image-encoding or complete metadata comparison.
Use original test copies: a resumed conversation has additional records.
"""
import argparse
import base64
import hashlib
import io
import json
from pathlib import Path
import re
import subprocess


def sha(data):
    return hashlib.sha256(data).hexdigest()


def load(path):
    data = Path(path).read_bytes()
    if str(path).endswith('.zst'):
        return subprocess.run(['zstd', '-qd', '--stdout', str(path)], check=True, capture_output=True).stdout
    return data


def normalized(data):
    from PIL import Image
    pictures = []

    def picture(match):
        raw = base64.b64decode(match.group(0).split(b',', 1)[1], validate=True)
        with Image.open(io.BytesIO(raw)) as image:
            image.load()
            content = str(image.size).encode() + image.convert('RGBA').tobytes() + (image.info.get('icc_profile') or b'')
        digest = sha(content)
        pictures.append(digest)
        return ('<decoded-picture:' + digest + '>').encode()

    result = re.sub(rb'data:image/[A-Za-z0-9.+-]+;base64,[A-Za-z0-9+/=]+', picture, data)
    return result, pictures


def main():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument('before', type=Path)
    parser.add_argument('after', type=Path)
    parser.add_argument('--mode', required=True, choices=['image-content', 'decoded-bytes'])
    args = parser.parse_args()
    before, after = load(args.before), load(args.after)
    result = {'mode': args.mode, 'beforeDecodedBytes': len(before), 'afterDecodedBytes': len(after),
              'beforeDecodedSHA256': sha(before), 'afterDecodedSHA256': sha(after),
              'decodedBytesIdentical': before == after, 'modelContinuationTested': False}
    if args.mode == 'image-content':
        a, pictures_a = normalized(before)
        b, pictures_b = normalized(after)
        result.update(beforeNormalizedSHA256=sha(a), afterNormalizedSHA256=sha(b),
                      beforeImageCount=len(pictures_a), afterImageCount=len(pictures_b),
                      passed=a == b and pictures_a == pictures_b)
    else:
        result['passed'] = before == after
    print(json.dumps(result, indent=2))
    raise SystemExit(0 if result['passed'] else 1)


if __name__ == '__main__':
    main()
