import argparse
import json
import re
import sys
import warnings
from pathlib import Path

from PIL import Image


def inspect(path, size=None, transparent=False):
    if not path.is_file() or path.stat().st_size > 20 * 1024 * 1024:
        raise ValueError("Missing file or file exceeds 20 MiB")
    Image.MAX_IMAGE_PIXELS = 16_000_000
    with warnings.catch_warnings():
        warnings.simplefilter("error", Image.DecompressionBombWarning)
        with Image.open(path) as image:
            if image.width * image.height > 16_000_000:
                raise ValueError("Image exceeds 16 million pixels")
            image.verify()
        with Image.open(path) as image:
            image.load()
            low, high = image.convert("RGBA").getchannel("A").getextrema()
            has_transparency = low < 255
            valid = (size is None or image.size == size) and (not transparent or has_transparency)
            return {"status": "passed" if valid else "failed", "format": image.format,
                    "width": image.width, "height": image.height,
                    "bytes": path.stat().st_size, "alpha_range": [low, high],
                    "has_transparent_pixels": has_transparency,
                    "manual_subject_and_text_review": "required"}


def main():
    parser = argparse.ArgumentParser(description="Offline file, size and transparent pixel check")
    parser.add_argument("file", type=Path)
    parser.add_argument("--size", help="Exact dimensions, for example 1024x1024")
    parser.add_argument("--transparent", action="store_true")
    args = parser.parse_args()
    size = None
    if args.size:
        if not re.fullmatch(r"[1-9][0-9]{0,4}x[1-9][0-9]{0,4}", args.size):
            parser.error("--size must be WIDTHxHEIGHT")
        size = tuple(map(int, args.size.split("x")))
    try:
        result = inspect(args.file, size, args.transparent)
    except (OSError, ValueError, Image.DecompressionBombError, Image.DecompressionBombWarning):
        result = {"status": "failed", "error": "File cannot be validated or exceeds local limits"}
    print(json.dumps(result, ensure_ascii=False, indent=2))
    return 0 if result["status"] == "passed" else 1


if __name__ == "__main__":
    sys.exit(main())
