#!/usr/bin/env python3

import sys
import json
from pathlib import Path

# ---------------------------------------------------------
# Positional args (aligned with PHP client exec call)
# ---------------------------------------------------------
# 1 query
# 2 limit
# 3 index_path
# 4 meta_path
# 5 model
#
# Example:
#   python vector_search_tags.py "foo" 8 /path/vector_tags.index /path/vector_tags.index.meta.json all-MiniLM-L6-v2
# ---------------------------------------------------------

if len(sys.argv) < 6:
    print("[]")
    sys.exit(0)

query = sys.argv[1]

try:
    limit = int(sys.argv[2])
except Exception:
    limit = 5

index_path = Path(sys.argv[3]).resolve()
meta_path  = Path(sys.argv[4]).resolve()
model_name = sys.argv[5]

# ---------------------------------------------------------
# Dependency checks
# ---------------------------------------------------------
try:
    import faiss
except Exception:
    # keep stdout clean for caller
    print("[]")
    sys.exit(0)

try:
    from sentence_transformers import SentenceTransformer
except Exception:
    print("[]")
    sys.exit(0)

from sentence_transformers import SentenceTransformer

# ---------------------------------------------------------
# File checks
# ---------------------------------------------------------
if limit <= 0:
    print("[]")
    sys.exit(0)

if not index_path.is_file() or not meta_path.is_file():
    # No tag index available => no routing
    print("[]")
    sys.exit(0)

# ---------------------------------------------------------
# Load model
# ---------------------------------------------------------
model = SentenceTransformer(model_name)

# ---------------------------------------------------------
# Load index + meta
# ---------------------------------------------------------
index = faiss.read_index(str(index_path))

try:
    with open(meta_path, "r", encoding="utf-8") as f:
        ids = json.load(f)
except Exception:
    print("[]")
    sys.exit(0)

if not isinstance(ids, list) or len(ids) == 0:
    print("[]")
    sys.exit(0)

# ---------------------------------------------------------
# Embed & search
# ---------------------------------------------------------
qvec = model.encode([query], normalize_embeddings=True)

scores, idxs = index.search(qvec, limit)

out = []
for score, idx in zip(scores[0], idxs[0]):
    if idx is None or idx < 0 or idx >= len(ids):
        continue
    out.append({
        "tag_id": str(ids[idx]),
        "score": float(score),
    })

print(json.dumps(out))
sys.exit(0)