import os, plistlib, shutil, subprocess, time

BASE = os.path.expanduser("~/Claude/Projects/에이전트구축")
PLIST = os.path.expanduser("~/Library/LaunchAgents/com.sean.feedserver.plist")
SERVER = os.path.join(BASE, "feedserver.py")
LOGDIR = os.path.join(BASE, "logs")
os.makedirs(LOGDIR, exist_ok=True)

SERVER_CODE = '''
import os, json, subprocess, http.server, socketserver

BASE = os.path.expanduser("~/Claude/Projects/에이전트구축")
PORT = 8899
TOKEN = "sx7k2m"
PY = "/opt/homebrew/bin/python3"
ALLOWED = {"collect_x": "collect_x.py", "collect_news": "collect_news.py"}

class H(http.server.SimpleHTTPRequestHandler):
    def __init__(self, *a, **kw):
        super().__init__(*a, directory=BASE, **kw)

    def log_message(self, *a):
        pass

    def do_GET(self):
        if self.path.startswith("/run/"):
            raw = self.path[5:]
            name, _, qs = raw.partition("?")
            name = name.strip("/")
            token = ""
            for part in qs.split("&"):
                if part.startswith("k="):
                    token = part[2:]
            if token != TOKEN:
                self.send_error(403, "bad token")
                return
            script = ALLOWED.get(name)
            if not script:
                self.send_error(404, "unknown job")
                return
            try:
                p = subprocess.run([PY, os.path.join(BASE, script)],
                                   cwd=BASE, capture_output=True,
                                   text=True, timeout=240)
                out = {"job": name, "returncode": p.returncode,
                       "stdout": p.stdout[-2000:], "stderr": p.stderr[-2000:]}
            except subprocess.TimeoutExpired:
                out = {"job": name, "returncode": -1, "error": "timeout 240s"}
            body = json.dumps(out, ensure_ascii=False).encode()
            self.send_response(200)
            self.send_header("Content-Type", "application/json; charset=utf-8")
            self.send_header("Content-Length", str(len(body)))
            self.end_headers()
            self.wfile.write(body)
            return
        super().do_GET()

class S(socketserver.ThreadingTCPServer):
    allow_reuse_address = True
    daemon_threads = True

S(("127.0.0.1", PORT), H).serve_forever()
'''

open(SERVER, "w").write(SERVER_CODE.lstrip())
print("feedserver.py 작성 완료")

if os.path.exists(PLIST):
    shutil.copy(PLIST, PLIST + ".bak")
    print("기존 plist 백업:", PLIST + ".bak")

d = {
    "Label": "com.sean.feedserver",
    "ProgramArguments": ["/opt/homebrew/bin/python3", SERVER],
    "WorkingDirectory": BASE,
    "RunAtLoad": True,
    "KeepAlive": True,
    "StandardOutPath": os.path.join(LOGDIR, "feedserver.out"),
    "StandardErrorPath": os.path.join(LOGDIR, "feedserver.err"),
}
plistlib.dump(d, open(PLIST, "wb"))
print("plist 갱신 완료")

uid = os.getuid()
subprocess.run(["launchctl", "bootout", f"gui/{uid}/com.sean.feedserver"], capture_output=True)
time.sleep(1)
subprocess.run(["launchctl", "bootstrap", f"gui/{uid}", PLIST], capture_output=True)
time.sleep(3)

r = subprocess.run(["curl", "-s", "-m", "10", "-o", "/dev/null", "-w", "%{http_code}",
                    "http://127.0.0.1:8899/x_feed.jsonl"], capture_output=True, text=True)
print("파일서빙 테스트:", r.stdout)
r2 = subprocess.run(["curl", "-s", "-m", "10", "-o", "/dev/null", "-w", "%{http_code}",
                     "http://127.0.0.1:8899/run/collect_x"], capture_output=True, text=True)
print("토큰없이 실행 시도(403이면 정상):", r2.stdout)
print("=== 세팅 완료 ===")
