#!/usr/bin/env python3
"""Differential test: compare Python croniter vs Rust croniter_rs on real-world expressions."""

import json, sys
from datetime import datetime

EXPRESSIONS_FILE = "/home/ubuntu-exp/cronproject/croniter-rs/tests/differential/github_actions_expressions.json"
RESULTS_FILE = "/home/ubuntu-exp/cronproject/croniter-rs/tests/differential/real_world_results.json"
ITERATIONS = 11
BASE_TIME = datetime(2025, 6, 15, 12, 0, 0)

from croniter_rs import croniter as rs_croniter
from croniter import croniter as py_croniter

with open(EXPRESSIONS_FILE) as f:
    expressions = json.load(f)

print(f"Testing {len(expressions)} expressions, {ITERATIONS} iterations each direction")
print(f"Base time: {BASE_TIME}")

passed = 0
failed = 0
errors = 0
failures = []
error_list = []

for i, expr in enumerate(expressions):
    if (i + 1) % 500 == 0:
        print(f"  Progress: {i+1}/{len(expressions)} (pass={passed} fail={failed} err={errors})")
    try:
        py_iter = py_croniter(expr, BASE_TIME)
        rs_iter = rs_croniter(expr, BASE_TIME)

        mismatch = False
        # Test get_next
        for j in range(ITERATIONS):
            py_val = py_iter.get_next(datetime)
            rs_val = rs_iter.get_next()
            if py_val != rs_val:
                failures.append({"expr": expr, "direction": "next", "iteration": j,
                                 "python": str(py_val), "rust": str(rs_val)})
                mismatch = True
                break

        if not mismatch:
            # Reset iterators for get_prev
            py_iter2 = py_croniter(expr, BASE_TIME)
            rs_iter2 = rs_croniter(expr, BASE_TIME)
            for j in range(ITERATIONS):
                py_val = py_iter2.get_prev(datetime)
                rs_val = rs_iter2.get_prev()
                if py_val != rs_val:
                    failures.append({"expr": expr, "direction": "prev", "iteration": j,
                                     "python": str(py_val), "rust": str(rs_val)})
                    mismatch = True
                    break

        if mismatch:
            failed += 1
        else:
            passed += 1
    except Exception as e:
        errors += 1
        error_list.append({"expr": expr, "error": str(e)})

total = passed + failed + errors
print(f"\n{'='*60}")
print(f"RESULTS: {total} total | {passed} passed | {failed} failed | {errors} errors")
print(f"Pass rate: {passed/total*100:.2f}%" if total else "No expressions tested")
print(f"{'='*60}")

if failures:
    print(f"\nFirst 10 failures:")
    for f_item in failures[:10]:
        print(f"  {f_item['expr']} [{f_item['direction']}#{f_item['iteration']}]: "
              f"py={f_item['python']} rs={f_item['rust']}")

if error_list:
    print(f"\nFirst 10 errors:")
    for e_item in error_list[:10]:
        print(f"  {e_item['expr']}: {e_item['error']}")

results = {
    "total": total, "passed": passed, "failed": failed, "errors": errors,
    "base_time": str(BASE_TIME), "iterations": ITERATIONS,
    "pass_rate": f"{passed/total*100:.2f}%" if total else "N/A",
    "failures": failures[:100], "errors_list": error_list[:100]
}
with open(RESULTS_FILE, "w") as f:
    json.dump(results, f, indent=2)
print(f"\nDetailed results saved to {RESULTS_FILE}")
