#!/usr/bin/env python3
"""
OpenClaw 本地代理服务器（安全增强版）
- Token 通过环境变量注入，前端无需传递 Authorization
- 静态文件服务: /home/ubuntu/Downloads/
- API 代理: /v1/* -> http://127.0.0.1:18789/v1/*
- 自动添加 CORS 头，解决浏览器跨域问题
- 完整透传后端 4xx/5xx 错误
"""

import json
import os
import urllib.request
import urllib.error
from http.server import HTTPServer, SimpleHTTPRequestHandler

# ========== 配置区 ==========
PORT = 8080
OPENCLAW_BACKEND = "http://127.0.0.1:18789"
ENV_FILE = "/etc/openclaw-proxy.env"
# ============================


def load_api_key():
    """从环境变量文件加载 API Key"""
    if os.path.exists(ENV_FILE):
        with open(ENV_FILE) as f:
            for line in f:
                line = line.strip()
                if line and not line.startswith("#") and "=" in line:
                    key, _, value = line.partition("=")
                    os.environ.setdefault(key.strip(), value.strip())

    api_key = os.environ.get("OPENCLAW_API_KEY", "")
    if not api_key:
        raise RuntimeError(
            f"OPENCLAW_API_KEY not set!\n"
            f"Please create {ENV_FILE} with:\n"
            f"  OPENCLAW_API_KEY=your_token_here\n"
            f"And set permissions: sudo chmod 600 {ENV_FILE}"
        )
    return api_key


OPENCLAW_API_KEY = load_api_key()


class ProxyHandler(SimpleHTTPRequestHandler):
    """支持静态文件 + API 反向代理的 Handler"""

    def do_OPTIONS(self):
        """处理浏览器预检请求"""
        self.send_response(200)
        self._send_cors_headers()
        self.end_headers()

    def do_GET(self):
        """GET 请求：/v1/* 走代理，其余走静态文件"""
        if self.path.startswith("/v1/"):
            self._proxy_request("GET")
        else:
            super().do_GET()

    def do_POST(self):
        """POST 请求：/v1/* 走代理，其余返回 405"""
        if self.path.startswith("/v1/"):
            self._proxy_request("POST")
        else:
            self.send_response(405)
            self.end_headers()

    # ---- 内部方法 ----

    def _send_cors_headers(self):
        self.send_header("Access-Control-Allow-Origin", "*")
        self.send_header("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
        self.send_header("Access-Control-Allow-Headers", "Content-Type, Authorization")

    def _proxy_request(self, method):
        """将 /v1/* 请求转发到 OpenClaw Gateway，自动注入服务端 Token"""
        target_url = f"{OPENCLAW_BACKEND}{self.path}"

        # 读取请求体
        content_length = int(self.headers.get("Content-Length", 0))
        body = self.rfile.read(content_length) if content_length > 0 else None

        # ✅ 始终使用环境变量中的 Key，忽略前端传来的 Authorization
        headers = {
            "Authorization": f"Bearer {OPENCLAW_API_KEY}",
        }
        ct = self.headers.get("Content-Type")
        if ct:
            headers["Content-Type"] = ct

        req = urllib.request.Request(target_url, data=body, headers=headers, method=method)

        try:
            with urllib.request.urlopen(req) as resp:
                resp_body = resp.read()
                self.send_response(resp.status)
                self._send_cors_headers()
                ct = resp.headers.get("Content-Type", "application/json")
                self.send_header("Content-Type", ct)
                self.end_headers()
                self.wfile.write(resp_body)

        except urllib.error.HTTPError as e:
            # ✅ 后端返回 4xx/5xx 时，原样透传状态码和响应体
            resp_body = e.read()
            print(f"[PROXY ERROR] Backend returned {e.code}: {resp_body.decode(errors='replace')}")
            self.send_response(e.code)
            self._send_cors_headers()
            self.send_header("Content-Type", "application/json")
            self.end_headers()
            self.wfile.write(resp_body)

        except Exception as e:
            # ✅ 连接拒绝、超时等网络层错误，返回详细 502
            error_msg = f"{type(e).__name__}: {e}"
            print(f"[PROXY ERROR] {error_msg}")
            self.send_response(502)
            self._send_cors_headers()
            self.send_header("Content-Type", "application/json")
            self.end_headers()
            self.wfile.write(json.dumps({"error": error_msg}).encode())


if __name__ == "__main__":
    print(f"Serving on http://0.0.0.0:{PORT} (Remote: http://124.220.7.130:{PORT})")
    print(f"Proxying /v1/* -> {OPENCLAW_BACKEND}")
    print(f"API Key loaded from {'environment' if 'OPENCLAW_API_KEY' in os.environ else ENV_FILE}")
    HTTPServer(("0.0.0.0", PORT), ProxyHandler).serve_forever()