#!/usr/bin/env python3
"""Microbenchmark for SDK embedding validation paths."""

from __future__ import annotations

import argparse
import math
import random
import statistics
import time
from collections.abc import Callable
from dataclasses import dataclass

try:
    import numpy as np
except Exception:  # pragma: no cover
    np = None  # type: ignore[assignment]


def validate_python(values: list[float]) -> list[float]:
    normalized = [float(v) for v in values]
    if not normalized:
        raise ValueError("embedding must be non-empty")
    if any(not math.isfinite(v) for v in normalized):
        raise ValueError("embedding contains non-finite values")
    return normalized


def validate_numpy(values: list[float] | np.ndarray[object, np.dtype[np.float32]]) -> list[float]:
    if np is None:
        raise RuntimeError("NumPy not installed")
    array = np.asarray(values, dtype=np.float32)
    if array.ndim != 1:
        raise ValueError("embedding must be 1D")
    if int(array.size) == 0:
        raise ValueError("embedding must be non-empty")
    if not bool(np.isfinite(array).all()):
        raise ValueError("embedding contains non-finite values")
    return [float(v) for v in array]


@dataclass(frozen=True)
class BenchResult:
    name: str
    dims: int
    mean_ms: float
    p95_ms: float


def run_benchmark(
    name: str,
    dims: int,
    fn: Callable[[object], list[float]],
    *,
    iterations: int,
    payload: object,
) -> BenchResult:
    samples: list[float] = []
    for _ in range(iterations):
        start = time.perf_counter()
        fn(payload)
        samples.append((time.perf_counter() - start) * 1000.0)
    samples.sort()
    p95_index = min(len(samples) - 1, int(len(samples) * 0.95))
    return BenchResult(
        name=name,
        dims=dims,
        mean_ms=statistics.fmean(samples),
        p95_ms=samples[p95_index],
    )


def format_markdown(results: list[BenchResult]) -> str:
    lines = [
        "| path | dims | mean_ms | p95_ms |",
        "| --- | ---: | ---: | ---: |",
    ]
    for item in results:
        lines.append(
            f"| {item.name} | {item.dims} | {item.mean_ms:.4f} | {item.p95_ms:.4f} |"
        )
    return "\n".join(lines)


def main() -> None:
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("--iterations", type=int, default=2000)
    parser.add_argument("--dims", type=str, default="384,768,1536")
    args = parser.parse_args()

    dims = [int(part.strip()) for part in args.dims.split(",") if part.strip()]
    results: list[BenchResult] = []
    for dim in dims:
        random.seed(7)
        list_payload = [random.random() for _ in range(dim)]
        results.append(
            run_benchmark(
                "python-loop",
                dim,
                validate_python,
                iterations=args.iterations,
                payload=list_payload,
            )
        )
        if np is not None:
            results.append(
                run_benchmark(
                    "numpy-fastpath(list-input)",
                    dim,
                    validate_numpy,
                    iterations=args.iterations,
                    payload=list_payload,
                )
            )
            ndarray_payload = np.asarray(list_payload, dtype=np.float32)
            results.append(
                run_benchmark(
                    "numpy-fastpath(ndarray-input)",
                    dim,
                    validate_numpy,
                    iterations=args.iterations,
                    payload=ndarray_payload,
                )
            )

    print(format_markdown(results))


if __name__ == "__main__":
    main()
