#!/usr/bin/env python3
"""
Serve the Stage A **Today Trades** shareable site (optional password).

::

    cd /Users/robzingale/trading_bot

    # 1) Refresh snapshot
    PYTHONUNBUFFERED=1 .venv/bin/python -m RenTech.monitor.build_today_trades_snapshot \\
      --nav 50000 --fund-scale 1.5 \\
      --held AMZN,QCOM,AXP,INTC,LRCX,AMAT,MU,AMD,GEV

    # 2) Serve (password via env or flag)
    TODAY_TRADES_PASSWORD='share-me' .venv/bin/python -m RenTech.monitor.serve_today_trades

    # → http://127.0.0.1:8765/today_trades.html

For a friend on your LAN, bind all interfaces::

    TODAY_TRADES_PASSWORD='share-me' .venv/bin/python -m RenTech.monitor.serve_today_trades \\
      --host 0.0.0.0 --port 8765
"""

from __future__ import annotations

import argparse
import base64
import os
import sys
from functools import partial
from http.server import SimpleHTTPRequestHandler, ThreadingHTTPServer
from pathlib import Path
from urllib.parse import urlparse

_REPO = Path(__file__).resolve().parents[2]
if str(_REPO) not in sys.path:
    sys.path.insert(0, str(_REPO))


class TodayTradesHandler(SimpleHTTPRequestHandler):
    password: str | None = None

    def _authorized(self) -> bool:
        if not self.password:
            return True
        auth = self.headers.get("Authorization", "")
        if auth.startswith("Bearer ") and auth[7:] == self.password:
            return True
        if auth.startswith("Basic "):
            try:
                raw = base64.b64decode(auth[6:]).decode("utf-8")
                # accept "user:password" or ":password"
                if raw.split(":", 1)[-1] == self.password:
                    return True
            except Exception:
                pass
        # HTML page itself is public; only protect the snapshot JSON
        path = urlparse(self.path).path
        if path.endswith("today_trades_snapshot.json"):
            return False
        return True

    def do_GET(self) -> None:  # noqa: N802
        path = urlparse(self.path).path
        if path.endswith("today_trades_snapshot.json") and not self._authorized():
            self.send_response(401)
            self.send_header("WWW-Authenticate", 'Bearer realm="RenTech Today"')
            self.send_header("Content-Type", "application/json")
            self.end_headers()
            self.wfile.write(b'{"error":"unauthorized"}')
            return
        return super().do_GET()

    def log_message(self, fmt: str, *args) -> None:
        sys.stderr.write("%s - %s\n" % (self.address_string(), fmt % args))


def main() -> None:
    ap = argparse.ArgumentParser(description=__doc__.split("\n\n")[0])
    ap.add_argument("--host", default="127.0.0.1")
    ap.add_argument("--port", type=int, default=8765)
    ap.add_argument(
        "--password",
        default=os.environ.get("TODAY_TRADES_PASSWORD", ""),
        help="Protect snapshot JSON (also set TODAY_TRADES_PASSWORD)",
    )
    ap.add_argument(
        "--root",
        type=Path,
        default=_REPO,
        help="HTTP document root (repo root so today_trades.html + RenTech/data/... resolve)",
    )
    args = ap.parse_args()
    root = args.root.expanduser().resolve()
    os.chdir(root)

    handler = partial(TodayTradesHandler, directory=str(root))
    TodayTradesHandler.password = str(args.password).strip() or None

    httpd = ThreadingHTTPServer((args.host, int(args.port)), handler)
    pw_note = "password ON" if TodayTradesHandler.password else "password OFF"
    print(f"Serving {root}")
    print(f"Open http://{args.host}:{args.port}/today_trades.html  ({pw_note})")
    if args.host in ("0.0.0.0", "::"):
        print("LAN: use this machine's IP instead of 0.0.0.0")
    try:
        httpd.serve_forever()
    except KeyboardInterrupt:
        print("\nStopped.")


if __name__ == "__main__":
    main()
