#!/usr/bin/env python3
"""Read a local folder of SVGs and print structural facts as JSON.

No files are changed. This is an inventory, not a sanitizer or visual review.
Requires Python 3.10 or later; no third-party packages.
"""
import argparse
import json
from pathlib import Path
import sys
import xml.etree.ElementTree as ET

SVG = "{http://www.w3.org/2000/svg}"
MAX_BYTES = 5 * 1024 * 1024


def inspect(path):
    row = {"file": path.name}
    try:
        # Read at most one byte over the limit, including if a file changes size.
        with path.open("rb") as stream:
            data = stream.read(MAX_BYTES + 1)
        row["bytes"] = len(data)
        if len(data) > MAX_BYTES:
            raise ValueError("File exceeds the 5 MiB inspection limit")
        text = data.decode("utf-8-sig")
        if "<!DOCTYPE" in text.upper() or "<!ENTITY" in text.upper():
            raise ValueError("DTD/entity declarations are outside this example's scope")
        root = ET.fromstring(text)
        if root.tag != SVG + "svg":
            raise ValueError("Root must be svg in the SVG namespace")
        elements = list(root.iter())
        row.update({
            "viewBox": root.get("viewBox"),
            "paths": sum(el.tag == SVG + "path" for el in elements),
            "images": sum(el.tag == SVG + "image" for el in elements),
            "fill_attributes": sorted({el.attrib["fill"] for el in elements if "fill" in el.attrib}),
            "stroke_attributes": sorted({el.attrib["stroke"] for el in elements if "stroke" in el.attrib}),
            "has_css": any(el.tag == SVG + "style" or "style" in el.attrib for el in elements),
            "status": "parsed",
        })
    except (OSError, UnicodeError, ET.ParseError, ValueError) as error:
        row.update({"status": "error", "error": str(error)})
    return row


def main():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("folder", type=Path, help="Folder containing UTF-8 SVG files (non-recursive)")
    args = parser.parse_args()
    if not args.folder.is_dir():
        parser.error("Supply an existing folder")
    files = sorted((p for p in args.folder.iterdir() if p.is_file() and p.suffix.lower() == ".svg"), key=lambda p: p.name)
    if not files:
        parser.error("No SVG files found in that folder")
    rows = [inspect(path) for path in files]
    print(json.dumps(rows, ensure_ascii=True, indent=2))
    return 1 if any(row["status"] == "error" for row in rows) else 0


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