#!/usr/bin/env python3
"""
SVG to PNG Renderer
==========
将 SVG 文件渲染为 PNG 图片。

依赖：
  pip install cairosvg Pillow

用法：
  # 基本用法（自动读取 SVG 尺寸）
  python svg-to-png.py input.svg output.png

  # 指定输出宽度（高度等比缩放）
  python svg-to-png.py input.svg output.png --width 1920

  # 指定输出高度（宽度等比缩放）
  python svg-to-png.py input.svg output.png --height 1080

  # 指定缩放因子（基于 SVG 原始尺寸放大 / 缩小）
  python svg-to-png.py input.svg output.png --scale 2

  # 批量转换目录下的所有 SVG
  python svg-to-png.py ./svg-dir/ ./png-dir/ --batch

  # 作为模块导入
  from svg_to_png import convert_svg_to_png
  convert_svg_to_png("input.svg", "output.png", scale=2)

路径：
  video-ai-system/tools/svg-to-png.py
"""

import argparse
import os
import sys
from pathlib import Path

try:
    import cairosvg
    from PIL import Image
except ImportError as e:
    print(f"[ERROR] 缺少依赖：{e}")
    print("请先安装：pip install cairosvg Pillow")
    sys.exit(1)


def convert_svg_to_png(
    svg_path: str,
    png_path: str,
    width: int = None,
    height: int = None,
    scale: float = None,
    background: str = "white",
) -> bool:
    """
    将单个 SVG 文件转换为 PNG。

    :param svg_path: 输入 SVG 文件路径
    :param png_path: 输出 PNG 文件路径
    :param width: 输出宽度（px），为 None 时保留 SVG 原始宽度
    :param height: 输出高度（px），为 None 时保留 SVG 原始高度
    :param scale: 缩放因子，基于 SVG 原始尺寸等比缩放
    :param background: 背景色，默认白色；设为 None 保留透明
    :return: 是否转换成功
    """
    if not os.path.isfile(svg_path):
        print(f"[ERROR] SVG 文件不存在：{svg_path}")
        return False

    # 确保输出目录存在
    os.makedirs(os.path.dirname(os.path.abspath(png_path)), exist_ok=True)

    try:
        # 构造 cairosvg 参数
        kwargs = {
            "url": svg_path,
            "write_to": png_path,
        }

        if background:
            kwargs["background_color"] = background

        if scale is not None:
            kwargs["scale"] = scale
        else:
            if width is not None:
                kwargs["output_width"] = width
            if height is not None:
                kwargs["output_height"] = height

        cairosvg.svg2png(**kwargs)

        # 验证输出文件
        if os.path.isfile(png_path):
            file_size = os.path.getsize(png_path)
            print(f"[OK] {svg_path} → {png_path}  ({file_size // 1024} KB)")
            return True
        else:
            print(f"[ERROR] 输出文件未生成：{png_path}")
            return False

    except Exception as e:
        print(f"[ERROR] 转换失败 {svg_path}：{e}")
        return False


def batch_convert(
    svg_dir: str,
    png_dir: str,
    width: int = None,
    height: int = None,
    scale: float = None,
) -> tuple:
    """
    批量转换目录下的所有 SVG 文件。

    :param svg_dir: 输入目录（包含 SVG 文件）
    :param png_dir: 输出目录
    :return: (成功数, 总数)
    """
    if not os.path.isdir(svg_dir):
        print(f"[ERROR] 输入目录不存在：{svg_dir}")
        return 0, 0

    os.makedirs(png_dir, exist_ok=True)

    svg_files = sorted(Path(svg_dir).glob("*.svg"))
    if not svg_files:
        print(f"[WARN] 目录中没有找到 SVG 文件：{svg_dir}")
        return 0, 0

    print(f"[INFO] 找到 {len(svg_files)} 个 SVG 文件，开始批量转换...")
    success = 0
    total = len(svg_files)

    for svg_file in svg_files:
        png_file = os.path.join(png_dir, svg_file.stem + ".png")
        if convert_svg_to_png(
            str(svg_file), png_file,
            width=width, height=height, scale=scale
        ):
            success += 1

    print(f"\n[INFO] 批量转换完成：{success}/{total} 成功")
    return success, total


def main():
    parser = argparse.ArgumentParser(
        description="SVG to PNG 渲染工具（基于 CairoSVG）",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
示例：
  python svg-to-png.py input.svg output.png
  python svg-to-png.py input.svg output.png --width 1920
  python svg-to-png.py ./svg/ ./png/ --batch --scale 2
"""
    )
    parser.add_argument("input", help="输入 SVG 文件或目录")
    parser.add_argument("output", help="输出 PNG 文件或目录")
    parser.add_argument("--width", type=int, default=None, help="输出宽度（px）")
    parser.add_argument("--height", type=int, default=None, help="输出高度（px）")
    parser.add_argument("--scale", type=float, default=None, help="缩放因子")
    parser.add_argument("--batch", action="store_true", help="批量转换模式")
    parser.add_argument("--background", default="white", help="背景色（默认 white，设为 'none' 保留透明）")

    args = parser.parse_args()

    if args.batch or os.path.isdir(args.input):
        # 批量模式
        success, total = batch_convert(
            args.input, args.output,
            width=args.width, height=args.height, scale=args.scale
        )
        sys.exit(0 if success == total else 1)
    else:
        # 单文件模式
        bg = None if args.background.lower() == "none" else args.background
        ok = convert_svg_to_png(
            args.input, args.output,
            width=args.width, height=args.height,
            scale=args.scale, background=bg
        )
        sys.exit(0 if ok else 1)


if __name__ == "__main__":
    main()
