#!/usr/bin/env python3
"""Serve SPA dist + proxy /pb to PocketBase + /deepseek to api.deepseek.com.

Reproducible from the spq-v2 deployment session. Drops into any PocketBase-backed
React SPA project that uses /pb as its PocketBase base URL. Serves the Vite build
output with SPA fallback, CORS headers, and PB/deepseek API proxying.

Usage:
  python3 spa-pb-proxy.py

Env vars (optional — defaults are for the ShopProQuote spq-v2 deployment):
  DIST_DIR  - path to the Vite dist/ directory
  PB_URL    - PocketBase URL (default: http://127.0.0.1:8091)
  PORT      - listen port (default: 4173)
  DS_KEY_FILE - path to file containing DeepSeek API key (default: /tmp/deepseek_key.txt)
"""

import os
import urllib.request
from http.server import HTTPServer, SimpleHTTPRequestHandler

DIST = os.environ.get('DIST_DIR', '/path/to/dist')
PB = os.environ.get('PB_URL', 'http://127.0.0.1:8091')
PORT = int(os.environ.get('PORT', '4173'))
DS_KEY_FILE = os.environ.get('DS_KEY_FILE', '/tmp/deepseek_key.txt')

class Handler(SimpleHTTPRequestHandler):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, directory=DIST, **kwargs)

    def end_headers(self):
        self.send_header('Access-Control-Allow-Origin', '*')
        self.send_header('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE, OPTIONS')
        self.send_header('Access-Control-Allow-Headers', 'Authorization, Content-Type')
        super().end_headers()

    def do_OPTIONS(self):
        self.send_response(204)
        self.end_headers()

    def do_GET(self):
        if self.path.startswith(('/pb', '/api', '/deepseek')):
            self.proxy()
        else:
            full = os.path.join(DIST, self.path.lstrip('/'))
            if not os.path.exists(full) or (os.path.isdir(full) and self.path != '/'):
                self.path = '/index.html'
            super().do_GET()

    def do_POST(self):
        if self.path.startswith(('/pb', '/api', '/deepseek')):
            self.proxy()
        else:
            self.send_error(405)

    def do_PUT(self):    self.proxy()
    def do_PATCH(self):  self.proxy()
    def do_DELETE(self): self.proxy()

    def proxy(self):
        # DeepSeek API
        if self.path.startswith('/deepseek'):
            url = 'https://api.deepseek.com' + self.path[len('/deepseek'):]
        # PB SDK: /pb/api/... → http://pb/api/...
        elif self.path.startswith('/pb'):
            url = PB + self.path[3:]
        else:
            url = PB + self.path

        body = None
        if self.headers.get('Content-Length'):
            body = self.rfile.read(int(self.headers['Content-Length']))

        req = urllib.request.Request(url, data=body, method=self.command)
        for k, v in self.headers.items():
            if k.lower() not in ('host', 'connection', 'origin', 'referer'):
                req.add_header(k, v)

        if self.path.startswith('/deepseek') and os.path.exists(DS_KEY_FILE):
            with open(DS_KEY_FILE) as f:
                req.add_header('Authorization', f'Bearer {f.read().strip()}')

        try:
            resp = urllib.request.urlopen(req)
            self.send_response(resp.status)
            for k, v in resp.headers.items():
                if k.lower() not in ('transfer-encoding', 'connection'):
                    self.send_header(k, v)
            self.end_headers()
            self.wfile.write(resp.read())
        except urllib.error.HTTPError as e:
            self.send_response(e.code)
            self.end_headers()
            self.wfile.write(e.read())

if __name__ == '__main__':
    server = HTTPServer(('0.0.0.0', PORT), Handler)
    print(f'Serving {DIST} on http://0.0.0.0:{PORT} (PB → {PB}, DeepSeek → api.deepseek.com)')
    server.serve_forever()
