"""Flask Web Server

所有 HTTP 路由集中在 backend.api 包管理,本文件仅负责:
1. 注册 Blueprint
2. 启动服务

启动方式:
    ./start.sh <notifier_name> <notifier_token>
"""

from __future__ import annotations

import sys

from flask import Flask

from backend.core.database import init_db
from backend.core.logger import get_logger
from backend.dispatcher.monitor import monitor
from backend.services import user_service

LOGGER = get_logger("backend.server")

app = Flask(__name__)

# ==================== 注册所有 Blueprint ====================

from backend.api import api_bp, webhook, static  # noqa: E402

# /webhook(无前缀)
app.register_blueprint(webhook.webhook_bp)
# /api/v1/*
app.register_blueprint(api_bp)
# / 静态文件托管(最后注册,作为兜底)
app.register_blueprint(static.static_bp)

# ==================== 启动入口 ====================

def main() -> None:
    """启动入口:解析参数 → 初始化 → 启动服务"""
    import argparse
    parser = argparse.ArgumentParser(description="CodeSpectra Webhook Server")
    parser.add_argument("--host", default="0.0.0.0", help="监听地址 (默认: 0.0.0.0)")
    parser.add_argument("--port", type=int, default=8000, help="监听端口 (默认: 8000)")
    parser.add_argument("--notifier-name", required=True, help="notifier 账户名")
    parser.add_argument("--notifier-token", required=True, help="notifier access_token")
    args = parser.parse_args()

    # 1. 建表
    init_db()

    # 2. 注册 handlers
    import backend.handlers  # noqa: F401

    # 3. 恢复监控数据,并清理路由配置中已移除命令的失效统计
    import atexit

    from backend.dispatcher.routes import collect_stat_keys
    from backend.services import monitor_service
    monitor.restore(
        total=monitor_service.load_total_requests(),
        cumulative_uptime=monitor_service.load_cumulative_uptime(),
        routes=monitor_service.load_route_stats(),
        peak=monitor_service.load_peak_window_count(),
    )
    stale_routes = monitor.prune_stale_route_stats(collect_stat_keys())
    if stale_routes:
        LOGGER.info(f"cleaned stale route stats: {stale_routes}")

    # 4. 监控持久化:退出时保存 + 每 5 分钟定时保存(低流量场景 uptime 不丢)
    atexit.register(monitor.persist)
    monitor.start_periodic_persist()

    # 5. 初始化 notifier 用户
    user_service.get_or_create_user(args.notifier_name, "notifier", access_token=args.notifier_token)
    user_service.update_user(args.notifier_name, type="notifier", access_token=args.notifier_token)
    LOGGER.info(f"notifier user [{args.notifier_name}] is ready")
    LOGGER.info("init successfully, starting server")
    # 6. 启动服务
    LOGGER.info(f"start waitress @ {args.host}:{args.port}")
    sys.stdout.flush()

    import waitress
    waitress.serve(
        app,
        host=args.host,
        port=args.port,
        threads=8,
        _quiet=True,
    )


if __name__ == "__main__":
    main()