#!/usr/bin/env python3
"""Compare two H3 renders: sampled-frame SSIM/PSNR + brightness/saturation/laplacian.
Usage: metrics.py <a.mp4> <b.mp4> [stride=12]
"""
import json, subprocess, sys
import numpy as np
import cv2

def frames(path, stride):
    cap = cv2.VideoCapture(path)
    out, i = [], 0
    while True:
        ok, f = cap.read()
        if not ok:
            break
        if i % stride == 0:
            out.append(f)
        i += 1
    cap.release()
    return out

def main():
    a_path, b_path = sys.argv[1], sys.argv[2]
    stride = int(sys.argv[3]) if len(sys.argv) > 3 else 12
    A, B = frames(a_path, stride), frames(b_path, stride)
    n = min(len(A), len(B))
    ssims, psnrs = [], []
    for fa, fb in zip(A[:n], B[:n]):
        g1 = cv2.cvtColor(fa, cv2.COLOR_BGR2GRAY)
        g2 = cv2.cvtColor(fb, cv2.COLOR_BGR2GRAY)
        ssims.append(cv2.matchTemplate(g1, g2, cv2.TM_CCOEFF_NORMED)[0][0] if False else _ssim(g1, g2))
        mse = float(np.mean((fa.astype(np.float64) - fb.astype(np.float64)) ** 2))
        psnrs.append(99.0 if mse == 0 else 10 * np.log10(255**2 / mse))
    def stats(x):
        return {"mean": round(float(np.mean(x)), 4), "p05": round(float(np.percentile(x, 5)), 4),
                "min": round(float(np.min(x)), 4)}
    la = float(cv2.Laplacian(cv2.cvtColor(A[len(A)//2], cv2.COLOR_BGR2GRAY), cv2.CV_64F).var())
    lb = float(cv2.Laplacian(cv2.cvtColor(B[len(B)//2], cv2.COLOR_BGR2GRAY), cv2.CV_64F).var())
    print(json.dumps({"frames_compared": n, "ssim": stats(ssims), "psnr": stats(psnrs),
                      "laplacian_midframe": {"A": round(la, 1), "B": round(lb, 1)},
                      "frame_counts": {"A": len(A), "B": len(B)}}, ensure_ascii=False))

def _ssim(g1, g2):
    C1, C2 = (0.01*255)**2, (0.03*255)**2
    g1 = g1.astype(np.float64); g2 = g2.astype(np.float64)
    mu1, mu2 = cv2.GaussianBlur(g1, (11,11), 1.5), cv2.GaussianBlur(g2, (11,11), 1.5)
    s1, s2 = mu1**2, mu2**2
    s12 = mu1*mu2
    sv1 = cv2.GaussianBlur(g1*g1, (11,11), 1.5) - s1
    sv2 = cv2.GaussianBlur(g2*g2, (11,11), 1.5) - s2
    svv = cv2.GaussianBlur(g1*g2, (11,11), 1.5) - s12
    num = (2*s12 + C1) * (2*svv + C2)
    den = (s1 + s2 + C1) * (sv1 + sv2 + C2)
    return float(np.mean(num/den))

if __name__ == "__main__":
    main()
