#!/usr/bin/env python3
"""
Transcribe an audio file using openai-whisper (CPU-only).

stdin:  JSON {"path": "...", "model": "tiny|base|small|medium|large-v3"}
stdout: JSON {"text": "...", "duration": null, "segments": []}
        or   {"error": "<kind>", "message": "..."}

Force-loads on CPU because the venv's torch may not match the local GPU
(e.g. a GT 1030 with sm_61 against a sm_75+ torch build) — those mismatches
print noisy CUDA warnings and then crash. CPU is slower but always works.
"""
import sys, os, json, warnings

# Quiet CUDA warnings from torch even though we won't use the GPU.
warnings.filterwarnings("ignore")
os.environ.setdefault("CUDA_VISIBLE_DEVICES", "")  # hide all GPUs
os.environ.setdefault("PYTHONWARNINGS", "ignore")

try:
    import whisper
except Exception as e:
    print(json.dumps({"error": "deps_missing", "message": str(e)}))
    sys.exit(0)


def main() -> None:
    raw = sys.stdin.read()
    try:
        data = json.loads(raw) if raw.strip() else {}
    except Exception as e:
        print(json.dumps({"error": "bad_input", "message": str(e)}))
        return

    path = data.get("path")
    if not path or not os.path.exists(path):
        print(json.dumps({"error": "file_not_found", "path": path or ""}))
        return

    model_name = data.get("model") or "tiny"
    try:
        model = whisper.load_model(model_name, device="cpu")
        result = model.transcribe(path, fp16=False)
    except Exception as e:
        print(json.dumps({"error": "whisper_failed", "message": str(e)}))
        return

    text = (result.get("text") or "").strip()
    raw_segments = result.get("segments") or []
    segments = [
        {
            "start": float(s.get("start", 0.0)),
            "end": float(s.get("end", 0.0)),
            "text": (s.get("text") or "").strip(),
        }
        for s in raw_segments
    ]
    duration = float(segments[-1]["end"]) if segments else None
    print(json.dumps({"text": text, "duration": duration, "segments": segments}))


if __name__ == "__main__":
    main()
