#!/usr/bin/env python3
"""Serve the Swapple design prototype from this package."""

from __future__ import annotations

import argparse
import functools
import http.server
import os
import socketserver
import sys
import threading
import time
import webbrowser
from pathlib import Path


ROOT = Path(__file__).resolve().parent
DEFAULT_PORT = 5180


class QuietHandler(http.server.SimpleHTTPRequestHandler):
    def log_message(self, format: str, *args: object) -> None:
        sys.stderr.write("%s - %s\n" % (self.log_date_time_string(), format % args))


def serve(port: int, open_browser: bool) -> None:
    os.chdir(ROOT)
    handler = functools.partial(QuietHandler, directory=str(ROOT))

    with socketserver.TCPServer(("127.0.0.1", port), handler) as httpd:
        httpd.allow_reuse_address = True
        url = f"http://127.0.0.1:{port}/prototype/index.html"
        print("")
        print("Swapple Editorial Orchard preview is running:")
        print(url)
        print("")
        print("Press Ctrl+C to stop.")
        print("")

        if open_browser:
            threading.Thread(target=lambda: (time.sleep(0.5), webbrowser.open(url)), daemon=True).start()

        httpd.serve_forever()


def main() -> None:
    parser = argparse.ArgumentParser(description="Run the Swapple redesign preview.")
    parser.add_argument("--port", type=int, default=DEFAULT_PORT, help=f"Port to serve on. Default: {DEFAULT_PORT}")
    parser.add_argument("--no-open", action="store_true", help="Do not open a browser automatically.")
    args = parser.parse_args()

    try:
        serve(args.port, open_browser=not args.no_open)
    except OSError as exc:
        if exc.errno in {48, 98, 10048}:
            print(f"Port {args.port} is already in use. Try:", file=sys.stderr)
            print(f"  python3 start_preview.py --port {args.port + 1}", file=sys.stderr)
        else:
            print(f"Could not start preview server: {exc}", file=sys.stderr)
        raise SystemExit(1)
    except KeyboardInterrupt:
        print("\nStopped Swapple preview.")


if __name__ == "__main__":
    main()

