#!/usr/bin/env python3
"""Run SetPassword from INSIDE the app page via Runtime.evaluate.
The page's own fetch attaches cookies + XSRF and resolves the right origin.
Tries the 'authentication' client endpoints. Reads creds from env file.
Prints which endpoint accepted (no secret values printed)."""
import json, urllib.request
from websocket import create_connection

def read_key(k):
    for line in open("/home/claude/.config/amd-agent/credentials.env"):
        if line.startswith(k+"="):
            return line[len(k)+1:].rstrip("\n")
    return ""
OLD=read_key("CUROGRAM_AGENT_PASSWORD"); NEW=read_key("AMD_PASSWORD")

tabs=json.loads(urllib.request.urlopen("http://localhost:9223/json",timeout=8).read())
page=next(t for t in tabs if t.get("type")=="page" and "app.curogram.com" in (t.get("url") or "").lower())
ws=create_connection(page["webSocketDebuggerUrl"],timeout=25)
_id=[0]
def call(method,params=None):
    _id[0]+=1; mid=_id[0]
    ws.send(json.dumps({"id":mid,"method":method,"params":params or {}}))
    while True:
        m=json.loads(ws.recv())
        if m.get("id")==mid:
            if "error" in m: raise RuntimeError(m["error"])
            return m.get("result",{})
call("Runtime.enable")

SETPW = ("mutation SetPassword($oldPassword: Password!, $password: Password!, "
         "$passwordConfirmation: Password!) { setPassword(oldPassword: $oldPassword, "
         "password: $password, passwordConfirmation: $passwordConfirmation) }")

# candidate endpoints for the 'authentication' apollo client
candidates = [
  "https://api-v2.curogram.com/authentication/graphql",
  "https://api-v2.curogram.com/authenticate/graphql",
  "https://api-v2.curogram.com/auth/graphql",
  "https://app.curogram.com/graphql",
  "https://stack.curogram.com/graphql",
  "https://api-v2.curogram.com/graphql",
]

js = """
(async (endpoints, q, oldp, newp) => {
  const getXsrf = () => {
    const m = document.cookie.match(/XSRF-TOKEN=([^;]+)/);
    return m ? decodeURIComponent(m[1]) : '';
  };
  const results = [];
  for (const url of endpoints) {
    try {
      const r = await fetch(url, {
        method: 'POST',
        credentials: 'include',
        headers: {
          'Content-Type': 'application/json',
          'Accept': 'application/json',
          'X-Curogram-Frontend': 'web',
          ...(getXsrf() ? {'X-XSRF-TOKEN': getXsrf()} : {})
        },
        body: JSON.stringify({operationName:'SetPassword', query:q,
          variables:{oldPassword:oldp, password:newp, passwordConfirmation:newp}})
      });
      let body; try { body = await r.json(); } catch(e){ body = {raw: await r.text()}; }
      const hasErr = body && body.errors;
      const validationMiss = hasErr && JSON.stringify(body.errors).includes('Cannot query field');
      results.push({url, status:r.status, ok: r.status===200 && !hasErr,
        validationMiss, errSummary: hasErr ? JSON.stringify(body.errors).slice(0,200) : null,
        dataKeys: body && body.data ? Object.keys(body.data) : null});
      if (r.status===200 && !hasErr) break; // success: stop, password now changed
    } catch(e) { results.push({url, error: String(e)}); }
  }
  return JSON.stringify(results);
})
"""
res = call("Runtime.evaluate", {
    "expression": f"({js})({json.dumps(candidates)}, {json.dumps(SETPW)}, {json.dumps(OLD)}, {json.dumps(NEW)})",
    "awaitPromise": True, "returnByValue": True, "timeout": 20000})
val = res.get("result",{}).get("value")
print(val)
ws.close()
