"""
Export the OpenCLIP ViT-B/32 visual encoder to ONNX.

Run once on any machine with Python + pip (no GPU needed):

    pip install open-clip-torch onnx
    python -m app.services.vision.export_models [--models-dir /data/models]

Produces:
    embed/visual.onnx   (~350 MB)
"""
import argparse
import logging
from pathlib import Path

logger = logging.getLogger(__name__)


def export_openclip_visual(models_dir: Path):
    import torch
    import open_clip

    out_dir = models_dir / "embed"
    out_dir.mkdir(parents=True, exist_ok=True)
    visual_path = out_dir / "visual.onnx"
    if visual_path.exists():
        logger.info("OpenCLIP visual.onnx already exists, skipping export")
        return

    logger.info("Loading OpenCLIP ViT-B-32 laion2b_s34b_b79k...")
    model, _, _ = open_clip.create_model_and_transforms(
        "ViT-B-32", pretrained="laion2b_s34b_b79k"
    )
    model.eval()

    logger.info("Exporting visual encoder → %s", visual_path)
    dummy = torch.randn(1, 3, 224, 224)
    torch.onnx.export(
        model.visual,
        dummy,
        str(visual_path),
        input_names=["image"],
        output_names=["embedding"],
        dynamic_axes={"image": {0: "batch"}},
        opset_version=14,
        dynamo=False,
    )
    logger.info("Visual encoder exported (%.1f MB)", visual_path.stat().st_size / 1e6)


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--models-dir", type=Path, default=Path("/data/models"))
    args = parser.parse_args()

    logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s")
    args.models_dir.mkdir(parents=True, exist_ok=True)
    export_openclip_visual(args.models_dir)


if __name__ == "__main__":
    main()
