#!/usr/bin/env python3
import json, sys, urllib.request, urllib.parse, urllib.error

CRED = "/home/claude/.config/credentials/ringcentral.json"
with open(CRED) as f:
    c = json.load(f)
BASE = c["server"]

def get_token():
    data = urllib.parse.urlencode({
        "grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
        "assertion": c["jwt"],
    }).encode()
    import base64
    auth = base64.b64encode(f'{c["client_id"]}:{c["client_secret"]}'.encode()).decode()
    req = urllib.request.Request(BASE + "/restapi/oauth/token", data=data, headers={
        "Authorization": "Basic " + auth,
        "Content-Type": "application/x-www-form-urlencoded",
    })
    with urllib.request.urlopen(req) as r:
        return json.load(r)["access_token"]

def api(tok, path, method="GET", body=None):
    url = BASE + path
    data = json.dumps(body).encode() if body is not None else None
    req = urllib.request.Request(url, data=data, method=method, headers={
        "Authorization": "Bearer " + tok,
        "Content-Type": "application/json",
        "Accept": "application/json",
    })
    try:
        with urllib.request.urlopen(req) as r:
            txt = r.read().decode()
            return json.loads(txt) if txt.strip() else {"_status": r.status}
    except urllib.error.HTTPError as e:
        body = e.read().decode()
        print(f"HTTP {e.code} on {method} {path}: {body}", file=sys.stderr)
        raise

if __name__ == "__main__":
    cmd = sys.argv[1] if len(sys.argv) > 1 else "queues"
    tok = get_token()
    if cmd == "queues":
        # call queues = extensions with type CallQueue
        res = api(tok, "/restapi/v1.0/account/~/call-queues?perPage=250")
        out = []
        for q in res.get("records", []):
            out.append({"id": q.get("id"), "name": q.get("name"), "ext": q.get("extensionNumber")})
        print(json.dumps(out, indent=2))
    elif cmd == "members":
        qid = sys.argv[2]
        res = api(tok, f"/restapi/v1.0/account/~/call-queues/{qid}/members?perPage=250")
        print(json.dumps(res, indent=2))
    elif cmd == "ext":
        # search extensions by name; optional filter args = extension numbers to keep
        res = api(tok, "/restapi/v1.0/account/~/extension?perPage=1000")
        wanted = set(sys.argv[2:])
        out = []
        for e in res.get("records", []):
            extnum = str(e.get("extensionNumber"))
            if wanted and extnum not in wanted:
                continue
            out.append({"id": e.get("id"), "ext": extnum,
                        "name": e.get("name"), "type": e.get("type"),
                        "status": e.get("status"),
                        "firstName": e.get("contact", {}).get("firstName"),
                        "lastName": e.get("contact", {}).get("lastName")})
        with open("/tmp/sab/ext_out.json", "w") as fo:
            json.dump(out, fo, indent=2)
        print(json.dumps(out, indent=2))
        print("WROTE /tmp/sab/ext_out.json")
    elif cmd == "cqpresence":
        # call-queue presence for a member extension id (accept-queue-calls per queue)
        eid = sys.argv[2]
        res = api(tok, f"/restapi/v1.0/account/~/extension/{eid}/call-queue-presence")
        with open("/tmp/sab/cqpresence_out.json", "w") as fo:
            json.dump(res, fo, indent=2)
        print(json.dumps(res, indent=2))
        print("WROTE /tmp/sab/cqpresence_out.json")
    elif cmd == "remove_member":
        # remove an extension from a queue. args: qid extnum CONFIRM
        qid = sys.argv[2]; extnum = sys.argv[3]
        confirm = sys.argv[4] if len(sys.argv) > 4 else ""
        before = api(tok, f"/restapi/v1.0/account/~/call-queues/{qid}/members?perPage=250")
        log = {"before_members": [r.get("extensionNumber") for r in before.get("records", [])]}
        if confirm != "CONFIRM_REMOVE":
            log["action"] = "DRY_RUN_no_change"
            with open("/tmp/sab/remove_log.json", "w") as fo:
                json.dump(log, fo, indent=2)
            print(json.dumps(log, indent=2)); print("DRY RUN - pass CONFIRM_REMOVE to execute")
        else:
            resp = api(tok, f"/restapi/v1.0/account/~/call-queues/{qid}/bulk-assign",
                       method="POST", body={"removedExtensionIds": [extnum]})
            after = api(tok, f"/restapi/v1.0/account/~/call-queues/{qid}/members?perPage=250")
            log["action"] = "REMOVED"
            log["put_response"] = resp
            log["after_members"] = [r.get("extensionNumber") for r in after.get("records", [])]
            with open("/tmp/sab/remove_log.json", "w") as fo:
                json.dump(log, fo, indent=2)
            print(json.dumps(log, indent=2)); print("WROTE /tmp/sab/remove_log.json")
    elif cmd == "add_member":
        # restore: add an extension to a queue. args: qid extnum CONFIRM
        qid = sys.argv[2]; extnum = sys.argv[3]
        confirm = sys.argv[4] if len(sys.argv) > 4 else ""
        if confirm != "CONFIRM_ADD":
            print("DRY RUN - pass CONFIRM_ADD to execute")
        else:
            resp = api(tok, f"/restapi/v1.0/account/~/call-queues/{qid}/bulk-assign",
                       method="POST", body={"addedExtensionIds": [extnum]})
            after = api(tok, f"/restapi/v1.0/account/~/call-queues/{qid}/members?perPage=250")
            print(json.dumps({"put_response": resp,
                              "after_members": [r.get("extensionNumber") for r in after.get("records", [])]}, indent=2))
    elif cmd == "presence":
        # queue member presence (accept queue calls status) for an extension
        eid = sys.argv[2]
        res = api(tok, f"/restapi/v1.0/account/~/extension/{eid}/presence?detailedTelephonyState=true")
        print(json.dumps(res, indent=2))
    else:
        print("unknown cmd")
