"""sm-evaluate コマンドラインエントリポイント．

PNG または luminance.npy を入力として均一性評価を実行し，
metrics.csv と可視化 PNG を出力ディレクトリに保存する．

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

matplotlib のバックエンドは Agg を強制する（headless 環境対応）．
evaluate は Mitsuba を使わないため，render.py と異なり遅延 import は不要．
ただし Agg バックエンドの設定順序を保つため，matplotlib.use() は pyplot import より前に置く．
"""

from __future__ import annotations

import argparse
import sys
from pathlib import Path

import matplotlib

# headless 環境（サーバ・CI 等）でも動くよう Agg バックエンドを強制する．
# pipeline（→ visualize.py）より先に設定することで，pyplot import 時に Agg が有効になる．
matplotlib.use("Agg")

# evaluate_image / EvaluationStepError 以外は，補助関数が本モジュールにあった頃の
# 参照互換のための再エクスポート（テスト・スクリプトが cli.evaluate.<名前> を参照している）．
from sm_tias_lightsim.evaluation.pipeline import (  # noqa: E402, F401
    _FIGURES_DIRNAME,
    _HISTOGRAM_FILENAME,
    _LUMINANCE_MAP_FILENAME,
    _METRICS_FILENAME,
    _RADIAL_PROFILE_FILENAME,
    _ZONE_MAP_FILENAME,
    EvaluationStepError,
    _apply_normalization_to_luminance,
    _apply_oetf_to_luminance,
    _load_eval_config,
    _load_luminance,
    _load_reference_luminance,
    _print_summary,
    _run_radial_min_max,
    _run_radial_profile,
    _run_shape_metrics,
    _run_zone_analysis,
    _save_figures,
    _save_metrics_csv,
    evaluate_image,
)
from sm_tias_lightsim.evaluation.radial import (  # noqa: E402, F401
    calc_radial_min_max_ratio,
    calc_radial_profile,
)


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

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

    Returns:
        パース済み Namespace．
    """
    parser = argparse.ArgumentParser(
        prog="sm-evaluate",
        description=(
            "PNG または luminance.npy を読み込み，均一性指標 CSV と可視化 PNG を出力する．"
        ),
    )
    parser.add_argument(
        "--image",
        "-i",
        required=True,
        type=Path,
        metavar="IMAGE_PATH",
        help="評価対象の画像ファイル（PNG または .npy）．",
    )
    parser.add_argument(
        "--config",
        "-c",
        required=True,
        type=Path,
        metavar="YAML_PATH",
        help="評価設定 YAML ファイルのパス（SceneConfig または EvaluationConfig 互換）．",
    )
    parser.add_argument(
        "--output",
        "-o",
        required=True,
        type=Path,
        metavar="OUTPUT_DIR",
        help="出力先ディレクトリ（存在しない場合は親ごと作成する）．",
    )
    parser.add_argument(
        "--no-figures",
        action="store_true",
        help="figures/ の可視化 PNG を作らない（指標だけ欲しいスイープ用．描画分だけ速い）．",
    )
    return parser.parse_args(argv)


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

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

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

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

    try:
        evaluate_image(
            args.image.resolve(),
            args.config.resolve(),
            args.output.resolve(),
            save_figures=not args.no_figures,
        )
    except EvaluationStepError as exc:
        print(f"エラー: {exc}", file=sys.stderr)
        return 1

    return 0
