# pyright: reportCallIssue=none
# Mitsuba 3 は variant ベースの動的属性解決を行うため Pylance/Pyright が
# mi.* を object 型と推論し reportCallIssue を誤検知する（coding-style.md の方針）．
# 処理本体（render_yaml）を main() 内で遅延 import しているのは，--help だけ使う場面
# （Mitsuba 不在の軽量環境）でも起動できるようにするためである．
# render/pipeline.py 自体も mitsuba 依存 import を関数内に閉じ込めており，
# llvm_* variant の DRJIT_LIBLLVM_PATH 設定が mitsuba import より前に走ることを保証する．
"""sm-render コマンドラインエントリポイント．

YAML シーン定義を読み込み，Mitsuba 3 でレンダリングを実行して
PNG と luminance.npy を出力ディレクトリに保存する．

処理本体は `render/pipeline.py` の `render_yaml()` にある（スイープ等から
プロセス内で直接呼べるようにするため）．本モジュールは引数のパースと，
例外 → 「エラー: …」表示 + 終了コード 1 への変換だけを担う．
"""

from __future__ import annotations

import argparse
import sys
from pathlib import Path


def _parse_args(argv: list[str] | None = None) -> argparse.Namespace:
    """コマンドライン引数をパースして返す．

    Args:
        argv: 引数リスト．None のとき sys.argv[1:] を使用．

    Returns:
        パース済み Namespace．
    """
    parser = argparse.ArgumentParser(
        prog="sm-render",
        description=(
            "YAML シーン定義から Mitsuba 3 でレンダリングし PNG と luminance.npy を出力する．"
        ),
    )
    parser.add_argument(
        "--scene",
        "-s",
        required=True,
        type=Path,
        metavar="YAML_PATH",
        help="シーン定義 YAML ファイルのパス．",
    )
    parser.add_argument(
        "--output",
        "-o",
        required=True,
        type=Path,
        metavar="OUTPUT_DIR",
        help="出力先ディレクトリ（存在しない場合は親ごと作成する）．",
    )
    parser.add_argument(
        "--variant",
        default=None,
        metavar="VARIANT",
        help=(
            "Mitsuba variant を上書きする（例: cuda_ad_rgb）．"
            "未指定なら環境変数 SM_RENDER_VARIANT，それも無ければ YAML の render.variant を使う．"
        ),
    )
    return parser.parse_args(argv)


def main(argv: list[str] | None = None) -> int:
    """sm-render コマンドのメインエントリポイント．

    引数をパースして `render_yaml()` を呼び，段階別のエラーを終了コードに変換する．
    レンダそのものの処理フローは `render/pipeline.py` の `render_yaml()` を参照．

    Args:
        argv: 引数リスト．None のとき sys.argv[1:] を使用．

    Returns:
        終了コード（成功時 0，失敗時 1）．
    """
    # argparse 自体のエラー（必須引数欠落等）は ArgumentParser が直接 sys.exit するため
    # ここでは ValueError / FileNotFoundError 等の実行時エラーのみ捕捉する
    args = _parse_args(argv)

    # mitsuba 依存のモジュールを読み込む前に引数をパースする（--help を軽量に保つ）
    from sm_tias_lightsim.render.pipeline import RenderStepError, render_yaml

    try:
        png_path, npy_path = render_yaml(
            args.scene.resolve(),
            args.output.resolve(),
            args.variant,
        )
    except RenderStepError as exc:
        print(f"エラー: {exc}", file=sys.stderr)
        return 1

    print(f"レンダリング完了: {png_path}")
    print(f"輝度マップ保存: {npy_path}")
    return 0
