#!/usr/bin/env python3
import argparse
import json
import os
import sys
import urllib.request
import urllib.error
import uuid


def load_config():
    candidates = [
        os.environ.get("OPENCLAW_CONFIG"),
        "/opt/openclaw/.openclaw/openclaw.json",
        os.path.expanduser("~/.openclaw/openclaw.json"),
    ]
    for path in candidates:
        if path and os.path.exists(path):
            with open(path, "r", encoding="utf-8") as f:
                return json.load(f)
    raise RuntimeError("openclaw config not found")


def resolve_provider(cfg):
    providers = cfg.get("models", {}).get("providers", {}) or {}
    if "clawkai" in providers:
        provider = providers["clawkai"]
    elif providers:
        provider = next(iter(providers.values()))
    else:
        raise RuntimeError("no providers configured")
    base_url = provider.get("baseUrl") or provider.get("base_url")
    api_key = provider.get("apiKey") or provider.get("api_key")
    if not base_url or not api_key:
        raise RuntimeError("provider baseUrl or apiKey missing")
    return base_url.rstrip("/"), api_key


def resolve_model(cfg, explicit):
    if explicit:
        return explicit
    env_model = os.environ.get("OPENCLAW_TRANSCRIPTION_MODEL_ID") or os.environ.get(
        "TRANSCRIPTION_MODEL_ID"
    )
    if env_model:
        return env_model
    for path in (
        "/opt/openclaw/.openclaw/transcription_model",
        os.path.expanduser("~/.openclaw/transcription_model"),
    ):
        if os.path.exists(path):
            with open(path, "r", encoding="utf-8") as f:
                value = f.read().strip()
            if value:
                return value
    return "openai/gpt-audio-mini"


def build_url(base_url):
    if base_url.endswith("/v1"):
        return f"{base_url}/audio/transcriptions"
    return f"{base_url}/v1/audio/transcriptions"


def build_multipart(file_path, fields):
    boundary = f"clawkai-{uuid.uuid4().hex}"
    crlf = "\r\n"
    parts = []
    for key, value in fields.items():
        parts.append(
            f"--{boundary}{crlf}"
            f'Content-Disposition: form-data; name="{key}"{crlf}{crlf}'
            f"{value}"
        )
    filename = os.path.basename(file_path)
    header = (
        f"--{boundary}{crlf}"
        f'Content-Disposition: form-data; name="file"; filename="{filename}"{crlf}'
        f"Content-Type: application/octet-stream{crlf}{crlf}"
    )
    body = crlf.join(parts).encode("utf-8") + crlf.encode("utf-8") + header.encode("utf-8")
    with open(file_path, "rb") as f:
        file_bytes = f.read()
    closing = f"{crlf}--{boundary}--{crlf}".encode("utf-8")
    return boundary, body + file_bytes + closing


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--file", required=True)
    parser.add_argument("--model")
    parser.add_argument("--language")
    args = parser.parse_args()

    if not os.path.exists(args.file):
        raise RuntimeError("audio file not found")

    cfg = load_config()
    base_url, api_key = resolve_provider(cfg)
    model = resolve_model(cfg, args.model)
    url = build_url(base_url)

    fields = {"model": model}
    if args.language:
        fields["language"] = args.language

    boundary, data = build_multipart(args.file, fields)
    req = urllib.request.Request(
        url,
        data=data,
        headers={
            "Content-Type": f"multipart/form-data; boundary={boundary}",
            "Authorization": f"Bearer {api_key}",
            "User-Agent": "curl/8.5.0",
        },
        method="POST",
    )

    try:
        with urllib.request.urlopen(req, timeout=300) as resp:
            body = resp.read()
    except urllib.error.HTTPError as err:
        detail = err.read().decode("utf-8", errors="ignore")
        raise RuntimeError(f"transcription request failed: {err.code} {detail}") from err

    payload = json.loads(body.decode("utf-8"))
    text = payload.get("text") or payload.get("transcript") or ""
    if not text:
        raise RuntimeError("transcription response missing text")
    print(json.dumps({"text": text, "model": model}))


if __name__ == "__main__":
    try:
        main()
    except Exception as exc:
        sys.stderr.write(str(exc) + "\n")
        sys.exit(1)
