"""调度器端到端测试 — Ex5 三连夜战 + 定时远征。

用法::

    # 默认: Ex5 H5 三连夜战 x30, 远征间隔 15min
    python testing/ops/scheduler.py

    # 指定设备和次数
    python testing/ops/scheduler.py 127.0.0.1:16384 --times 10

    # 使用自定义 YAML
    python testing/ops/scheduler.py --plan examples/plans/event/20260212/Ex5A夜战.yaml --times 50

前置要求: 游戏处于任意正常页面。
"""

from __future__ import annotations

import argparse
import io
import sys
from pathlib import Path


# ── UTF-8 输出兼容（Windows 终端）──
try:
    if hasattr(sys.stdout, 'reconfigure'):
        sys.stdout.reconfigure(encoding='utf-8', errors='replace')  # type: ignore[union-attr]
        sys.stderr.reconfigure(encoding='utf-8', errors='replace')  # type: ignore[union-attr]
except Exception:
    try:
        if isinstance(sys.stdout, io.TextIOWrapper):
            sys.stdout = io.TextIOWrapper(
                sys.stdout.buffer, encoding='utf-8', errors='replace', line_buffering=True
            )
        if isinstance(sys.stderr, io.TextIOWrapper):
            sys.stderr = io.TextIOWrapper(
                sys.stderr.buffer, encoding='utf-8', errors='replace', line_buffering=True
            )
    except Exception:
        pass

from loguru import logger

from autowsgr.combat import CombatPlan
from autowsgr.ops.event_fight import EventFightRunner
from autowsgr.scheduler import FightTask, TaskScheduler
from autowsgr.types import ConditionFlag
from testing.ops._framework import launch_for_test


# ── 默认值 ──
_DEFAULT_PLAN_YAML = str(
    Path(__file__).parent.parent.parent
    / 'examples'
    / 'plans'
    / 'event'
    / '20260212'
    / 'Ex5A夜战.yaml'
)
_DEFAULT_TIMES = 30
_DEFAULT_MAP_CODE = 'H5'
_DEFAULT_EXPEDITION_INTERVAL = 900  # 15 分钟


def _parse_args() -> argparse.Namespace:
    parser = argparse.ArgumentParser(
        description='调度器端到端测试 — Ex5 三连夜战 + 定时远征',
        formatter_class=argparse.RawDescriptionHelpFormatter,
    )
    parser.add_argument(
        'serial',
        nargs='?',
        default=None,
        metavar='SERIAL',
        help='ADB serial（留空则自动检测唯一设备）',
    )
    parser.add_argument(
        '--plan',
        default=_DEFAULT_PLAN_YAML,
        metavar='YAML',
        help='战斗计划 YAML（默认: Ex5A夜战.yaml）',
    )
    parser.add_argument(
        '--map-code',
        default=_DEFAULT_MAP_CODE,
        metavar='CODE',
        help=f'活动地图代号（默认: {_DEFAULT_MAP_CODE}）',
    )
    parser.add_argument(
        '--times',
        type=int,
        default=_DEFAULT_TIMES,
        metavar='N',
        help=f'战斗次数（默认: {_DEFAULT_TIMES}）',
    )
    parser.add_argument(
        '--expedition-interval',
        type=int,
        default=_DEFAULT_EXPEDITION_INTERVAL,
        metavar='SEC',
        help=f'远征检查间隔秒数（默认: {_DEFAULT_EXPEDITION_INTERVAL}）',
    )
    parser.add_argument(
        '--log-dir',
        default=None,
        metavar='DIR',
        help='日志输出目录（默认: logs/interactive/scheduler）',
    )
    return parser.parse_args()


def main() -> None:
    args = _parse_args()

    log_dir = Path(args.log_dir) if args.log_dir else Path('logs/interactive/scheduler')

    serial = args.serial or None

    # ── 连接并启动游戏 ──
    try:
        ctx = launch_for_test(serial, log_dir=log_dir)
    except Exception as exc:
        print(f'[ERROR] 启动失败: {exc}')
        sys.exit(1)
    ctrl = ctx.ctrl

    logger.info('=' * 60)
    logger.info('调度器 E2E 测试 — Ex5 三连夜战 + 远征')
    logger.info('  计划: {}', args.plan)
    logger.info('  地图: {}', args.map_code)
    logger.info('  次数: {}', args.times)
    logger.info('  远征: 每 {}s', args.expedition_interval)
    logger.info('已连接: {}', ctrl.serial)
    logger.info('=' * 60)

    # ── 加载计划 ──
    plan = CombatPlan.from_yaml(args.plan)
    logger.info('已加载计划: {} ({})', plan.name, args.plan)

    # ── 构建 Runner ──
    runner = EventFightRunner(ctx, plan, map_code=args.map_code, fleet_id=2)

    # ── 构建调度器 ──
    scheduler = TaskScheduler(
        ctx,
        expedition_interval=float(args.expedition_interval),
    )
    scheduler.add(
        FightTask(
            runner=runner,
            times=args.times,
            name=f'Ex5夜战-{args.map_code}',
        )
    )

    # ── 运行 ──
    logger.info('开始调度...')
    try:
        tasks = scheduler.run()
    except Exception as exc:
        logger.exception('调度异常: {}', exc)
        sys.exit(1)

    # ── 结果 ──
    task = tasks[0]
    success = sum(1 for r in task.results if r.flag == ConditionFlag.OPERATION_SUCCESS)
    logger.info('=' * 60)
    logger.info('完成: {}/{} 成功', success, task.completed)
    logger.info('=' * 60)


if __name__ == '__main__':
    main()
