"""Inspect real browser downloads only. Never produces a converter output.

Usage: python inspect_downloads.py downloaded-file.ico [more.ico ...]
Outputs JSON to stdout. Refuses malformed/truncated ICO entries.
"""
import hashlib
import json
import struct
import sys
from pathlib import Path
from PIL import Image

def inspect(path):
    p = Path(path)
    b = p.read_bytes()
    if len(b) < 6:
        raise ValueError('ICO header missing')
    reserved, kind, count = struct.unpack_from('<HHH', b)
    if (reserved, kind) != (0, 1) or not count or len(b) < 6 + 16 * count:
        raise ValueError('Invalid ICO header or truncated directory')
    entries = []
    for i in range(count):
        w, h, colors, zero, planes, bits, size, offset = struct.unpack_from('<BBBBHHII', b, 6 + 16*i)
        if offset < 6 + 16*count or offset + size > len(b):
            raise ValueError(f'Entry {i} points outside payload bounds')
        payload = b[offset:offset+size]
        entries.append({'index':i,'directory_width':w or 256,'directory_height':h or 256,
                        'bits':bits,'payload_bytes':size,'offset':offset,
                        'payload_encoding':'PNG' if payload.startswith(b'\x89PNG\r\n\x1a\n') else 'DIB/other',
                        'payload_sha256':hashlib.sha256(payload).hexdigest()})
    im = Image.open(p)
    decoded=[]
    for size in sorted(im.ico.sizes()):
        frame=im.ico.getimage(size).convert('RGBA')
        decoded.append({'size':list(size),'alpha_extrema':list(frame.getchannel('A').getextrema()),
                        'corner_rgba':list(frame.getpixel((0,0))),
                        'center_rgba':list(frame.getpixel((size[0]//2,size[1]//2))),
                        'rgba_sha256':hashlib.sha256(frame.tobytes()).hexdigest()})
    return {'file':p.name,'bytes':len(b),'sha256':hashlib.sha256(b).hexdigest(),
            'directory_entries':entries,'pillow_decoded':decoded}

if __name__=='__main__':
    if len(sys.argv)<2:
        raise SystemExit('Supply real downloaded ICO files; no files supplied, no measurements made.')
    print(json.dumps([inspect(p) for p in sys.argv[1:]],indent=2))
