from __future__ import annotations

import argparse
import hashlib
import json
import zipfile
from pathlib import Path


def sha256_bytes(data: bytes) -> str:
    """函数说明：封装sha256_bytes方法的核心处理流程。"""
    return hashlib.sha256(data).hexdigest()


def package_index(path: Path) -> dict[str, str]:
    """函数说明：封装package_index方法的核心处理流程。"""
    index: dict[str, str] = {}
    with zipfile.ZipFile(path) as archive:
        for name in sorted(archive.namelist()):
            index[name] = sha256_bytes(archive.read(name))
    return index


def compare_packages(left: Path, right: Path) -> dict:
    """函数说明：封装compare_packages方法的核心处理流程。"""
    left_index = package_index(left)
    right_index = package_index(right)

    left_only = sorted(set(left_index) - set(right_index))
    right_only = sorted(set(right_index) - set(left_index))
    changed = sorted(
        name
        for name in set(left_index).intersection(right_index)
        if left_index[name] != right_index[name]
    )

    return {
        "left": str(left),
        "right": str(right),
        "identical": not left_only and not right_only and not changed,
        "left_only": left_only,
        "right_only": right_only,
        "changed": changed,
        "entry_count_left": len(left_index),
        "entry_count_right": len(right_index),
    }


def main() -> None:
    """函数说明：脚本主入口，负责串联参数解析与执行流程。"""
    parser = argparse.ArgumentParser(description="Compare two pptx packages entry-by-entry.")
    parser.add_argument("left", help="Left pptx file")
    parser.add_argument("right", help="Right pptx file")
    parser.add_argument("--output", help="Optional json output path")
    # 关键行注释：解析命令行参数，生成本次运行配置。
    args = parser.parse_args()

    result = compare_packages(Path(args.left), Path(args.right))
    payload = json.dumps(result, ensure_ascii=False, indent=2)
    if args.output:
        output = Path(args.output)
        output.parent.mkdir(parents=True, exist_ok=True)
        output.write_text(payload, encoding="utf-8")
    else:
        print(payload)


# 关键行注释：脚本直接运行时，从这里进入主流程。
if __name__ == "__main__":
    main()
