#!/usr/bin/env python3
"""
Generic Grist API wrapper using Vault for token retrieval.
Usage: python3 vault_grist_api.py <METHOD> <API_PATH> [JSON_PAYLOAD]
Example: python3 vault_grist_api.py GET /api/docs/wmBGUbgBveCdeY8fZ6T6eL/tables/Intune/records
"""

import sys
import json
import urllib.request
import urllib.error

VAULT_URL = "https://beavault.beawit.net:8200"
GRIST_URL = "https://grist.beawit.net"

def vault_auth():
    """Authenticate to Vault and return client token."""
    auth_data = json.dumps({
        "role_id": "75d2dcfb-9c65-7f60-59b4-eee8c7f8dc0e",
        "secret_id": "6202b465-2f25-547c-ec07-f47cfc4dda3e"
    }).encode()
    
    req = urllib.request.Request(
        f"{VAULT_URL}/v1/auth/approle/login",
        data=auth_data,
        headers={"Content-Type": "application/json"},
        method="POST"
    )
    
    with urllib.request.urlopen(req) as resp:
        data = json.loads(resp.read())
        return data["auth"]["client_token"]

def get_grist_token(vault_token):
    """Retrieve Grist API token from Vault."""
    req = urllib.request.Request(
        f"{VAULT_URL}/v1/kv/data/api/integration/grist",
        headers={"X-Vault-Token": vault_token}
    )
    
    with urllib.request.urlopen(req) as resp:
        data = json.loads(resp.read())
        return data["data"]["data"]["token"]

def grist_api_call(method, api_path, payload=None):
    """Make authenticated Grist API call."""
    # Step 1: Vault auth
    vault_token = vault_auth()
    
    # Step 2: Get Grist token
    grist_token = get_grist_token(vault_token)
    
    # Step 3: Make API call
    url = f"{GRIST_URL}{api_path}"
    headers = {
        "Authorization": f"Bearer {grist_token}",
        "Content-Type": "application/json"
    }
    
    if method == "GET":
        req = urllib.request.Request(url, headers=headers)
        with urllib.request.urlopen(req) as resp:
            return json.loads(resp.read())
    elif method == "PATCH":
        data = json.dumps(payload).encode() if payload else None
        req = urllib.request.Request(url, data=data, headers=headers, method="PATCH")
        with urllib.request.urlopen(req) as resp:
            return resp.read().decode()
    else:
        raise ValueError(f"Unsupported method: {method}")

def main():
    if len(sys.argv) < 3:
        print("Usage: python3 vault_grist_api.py <METHOD> <API_PATH> [JSON_PAYLOAD_FILE]")
        sys.exit(1)
    
    method = sys.argv[1].upper()
    api_path = sys.argv[2]
    payload = None
    
    if len(sys.argv) > 3:
        with open(sys.argv[3]) as f:
            payload = json.load(f)
    
    result = grist_api_call(method, api_path, payload)
    print(json.dumps(result, indent=2))

if __name__ == "__main__":
    main()
