"""一次运行四个轨迹实验绘图脚本。"""

from __future__ import annotations

import argparse
import os
import subprocess
import sys
from concurrent.futures import ThreadPoolExecutor, as_completed
from pathlib import Path


SCRIPT_NAMES = (
    "plot_trajectory_comparison.py",
    "plot_tracking_errors.py",
    "plot_speed_response.py",
    "plot_angular_command.py",
)


def build_command(
    script_path: Path,
    files: list[str],
    frequency_hz: float,
    filter_window_seconds: float,
    output_directory: str | None,
    show: bool,
) -> list[str]:
    """为一个绘图脚本构造与统一入口一致的命令行参数。"""
    command = [
        sys.executable,
        str(script_path),
        *files,
        "--frequency",
        str(frequency_hz),
        "--window",
        str(filter_window_seconds),
    ]

    if output_directory:
        command.extend(["--output-dir", output_directory])

    if show:
        command.append("--show")

    return command


def run_script(
    script_path: Path,
    files: list[str],
    frequency_hz: float,
    filter_window_seconds: float,
    output_directory: str | None,
    show: bool,
) -> tuple[str, int, str, str]:
    """运行一个绘图脚本并返回名称、退出码及标准输出和错误。"""
    result = subprocess.run(
        build_command(
            script_path,
            files,
            frequency_hz,
            filter_window_seconds,
            output_directory,
            show,
        ),
        cwd=script_path.parent,
        capture_output=True,
        text=True,
        encoding="utf-8",
        errors="replace",
        env={
            **os.environ,
            "PYTHONIOENCODING": "utf-8",
        },
        check=False,
    )

    return (
        script_path.name,
        result.returncode,
        result.stdout.strip(),
        result.stderr.strip(),
    )


def main() -> None:
    """并行执行四类实验图的生成任务。"""
    parser = argparse.ArgumentParser(
        description="一次生成轨迹、误差、速度响应和角速度指令四类图。"
    )
    parser.add_argument(
        "files",
        nargs="*",
        help="一个或多个CSV文件；省略时处理data_process目录下全部CSV。",
    )
    parser.add_argument(
        "--frequency",
        type=float,
        default=20.0,
        help="固定重采样频率，默认20 Hz。",
    )
    parser.add_argument(
        "--window",
        type=float,
        default=0.55,
        help="Savitzky-Golay滤波窗口，默认0.55 s。",
    )
    parser.add_argument(
        "--output-dir",
        help="图片输出目录；省略时由各绘图脚本使用默认目录。",
    )
    parser.add_argument(
        "--show",
        action="store_true",
        help="生成后请求显示图片。",
    )
    args = parser.parse_args()

    if args.frequency <= 0.0:
        parser.error("--frequency必须大于0。")

    if args.window <= 0.0:
        parser.error("--window必须大于0。")

    script_directory = Path(__file__).resolve().parent
    script_paths = [
        script_directory / name
        for name in SCRIPT_NAMES
    ]
    missing_scripts = [
        str(path)
        for path in script_paths
        if not path.is_file()
    ]
    if missing_scripts:
        parser.error(
            "缺少绘图脚本：" + "，".join(missing_scripts)
        )

    print("开始并行生成四类实验图……")
    failures: list[str] = []

    with ThreadPoolExecutor(
        max_workers=len(script_paths)
    ) as executor:
        futures = [
            executor.submit(
                run_script,
                script_path,
                args.files,
                args.frequency,
                args.window,
                args.output_dir,
                args.show,
            )
            for script_path in script_paths
        ]

        for future in as_completed(futures):
            script_name, return_code, stdout, stderr = (
                future.result()
            )
            print(f"\n[{script_name}]")
            if stdout:
                print(stdout)
            if stderr:
                print(stderr, file=sys.stderr)

            if return_code == 0:
                print("执行成功。")
            else:
                failures.append(script_name)
                print(
                    f"执行失败，退出码={return_code}。",
                    file=sys.stderr,
                )

    if failures:
        print(
            "\n以下脚本执行失败：" +
            "，".join(failures),
            file=sys.stderr,
        )
        raise SystemExit(1)

    print("\n四类实验图均已生成。")


if __name__ == "__main__":
    main()
