#!/usr/bin/env python3
"""
一次性文件下载服务器。
启动后服务指定文件任意次，文件被下载一次后自动退出。
同时有超时保护（默认300秒）。
"""
import argparse
import signal
import sys
import threading
import time
from http.server import HTTPServer, SimpleHTTPRequestHandler


class OneShotFileHandler(SimpleHTTPRequestHandler):
    """只服务一个文件，下载后自动关闭服务器"""

    downloaded = False
    file_to_serve = None
    download_timeout = 300  # 秒

    def log_message(self, format, *args):
        # 只打印关键信息
        pass

    def do_GET(self):
        if self.path == "/" or self.path == f"/{self.file_to_serve.name}":
            # 记录下载时间
            self.downloaded = True
            print(f"[serve_and_send] 文件被下载，触发关闭...", flush=True)
            # 通知主线程关闭
            self.server.shutdown_event.set()
            super().do_GET()
        else:
            self.send_error(404)

    def do_HEAD(self):
        self.do_GET()


class OneShotHTTPServer(HTTPServer):
    def __init__(self, *args, file_to_serve, **kwargs):
        super().__init__(*args, **kwargs)
        self.file_to_serve = file_to_serve
        self.shutdown_event = threading.Event()


def serve_and_send(port: int, file_path: str, timeout: int = 300):
    """启动一次性文件服务器，被下载后自动关闭"""
    import os
    file_name = os.path.basename(file_path)
    handler = type('Handler', (OneShotFileHandler,), {
        'file_to_serve': type('F', (), {'name': file_name})(),
    })

    # 切换到文件所在目录
    os.chdir(os.path.dirname(os.path.abspath(file_path)))

    server = OneShotHTTPServer(('0.0.0.0', port), handler, file_to_serve=handler.file_to_serve)
    server.timeout = 5  # 每5秒检查一次是否该关闭

    print(f"[serve_and_send] 启动服务器: http://0.0.0.0:{port}/{file_name}", flush=True)
    print(f"[serve_and_send] 超时时间: {timeout}秒", flush=True)

    # 在后台线程运行服务器
    server_thread = threading.Thread(target=server.serve_forever, daemon=True)
    server_thread.start()

    # 等待关闭信号（文件被下载 或 超时）
    shutdown_reason = server.shutdown_event.wait(timeout=timeout)

    print(f"[serve_and_send] 关闭服务器 (reason={'download' if shutdown_reason else 'timeout'})", flush=True)
    server.shutdown()
    server_thread.join(timeout=3)
    print("[serve_and_send] 完成", flush=True)


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='一次性文件下载服务器')
    parser.add_argument('--port', type=int, default=18789, help='监听端口')
    parser.add_argument('--file', type=str, required=True, help='要服务的文件路径')
    parser.add_argument('--timeout', type=int, default=300, help='超时秒数')
    args = parser.parse_args()

    serve_and_send(args.port, args.file, args.timeout)
