#!/usr/bin/env python3
"""
Analysis tool for differential test results.
Provides insights into test failures and patterns.
"""

import json
import sys
from pathlib import Path
from collections import Counter, defaultdict


def analyze_results(results_file: str):
    """Analyze test results and provide insights."""
    with open(results_file, 'r') as f:
        results = json.load(f)

    print(f"{'='*80}")
    print(f"Analysis of: {results_file}")
    print(f"{'='*80}\n")

    # Overall statistics
    total = results['passed'] + results['failed'] + results['errors']
    print(f"Overall Statistics:")
    print(f"  Total tests: {total}")
    print(f"  Passed: {results['passed']} ({100*results['passed']/total if total > 0 else 0:.1f}%)")
    print(f"  Failed: {results['failed']} ({100*results['failed']/total if total > 0 else 0:.1f}%)")
    print(f"  Errors: {results['errors']} ({100*results['errors']/total if total > 0 else 0:.1f}%)")

    if not results['failures']:
        print("\n✓ All tests passed!")
        return

    print(f"\n{'='*80}")
    print("Failure Analysis")
    print(f"{'='*80}\n")

    # Categorize failures
    failure_categories = defaultdict(list)
    operator_failures = Counter()
    field_failures = Counter()

    for failure in results['failures']:
        expr = failure['expr']
        desc = failure['description']

        # Categorize by operator
        if 'L' in expr:
            failure_categories['Last day (L)'].append(desc)
            operator_failures['L'] += 1
        if '#' in expr:
            failure_categories['Nth weekday (#)'].append(desc)
            operator_failures['#'] += 1
        if 'H' in expr:
            failure_categories['Hash (H)'].append(desc)
            operator_failures['H'] += 1
        if 'R' in expr:
            failure_categories['Random (R)'].append(desc)
            operator_failures['R'] += 1
        if '/' in expr:
            operator_failures['/'] += 1
        if '-' in expr and 'L-' not in expr:
            operator_failures['-'] += 1
        if ',' in expr:
            operator_failures[','] += 1

        # Count fields
        field_count = len(expr.split())
        field_failures[f'{field_count}-field'] += 1

        # Check for specific error patterns
        if failure.get('next_result', {}).get('error'):
            error = failure['next_result']['error']
            if 'out of range' in error:
                failure_categories['Range errors'].append(desc)
            elif 'not acceptable' in error:
                failure_categories['Syntax errors'].append(desc)

    # Print failure categories
    print("Failure Categories:")
    for category, failures in sorted(failure_categories.items()):
        print(f"\n  {category}: {len(failures)} failures")
        for i, desc in enumerate(failures[:3]):
            print(f"    - {desc}")
        if len(failures) > 3:
            print(f"    ... and {len(failures) - 3} more")

    # Print operator statistics
    if operator_failures:
        print(f"\n{'='*80}")
        print("Failures by Operator:")
        for op, count in operator_failures.most_common():
            print(f"  {op}: {count}")

    # Print field statistics
    if field_failures:
        print(f"\n{'='*80}")
        print("Failures by Field Count:")
        for field, count in sorted(field_failures.items()):
            print(f"  {field}: {count}")

    # Print top failures
    print(f"\n{'='*80}")
    print("Top 10 Failures (detailed):")
    print(f"{'='*80}")
    for i, failure in enumerate(results['failures'][:10]):
        print(f"\n{i+1}. {failure['description']}")
        print(f"   Expression: {failure['expr']}")
        print(f"   Start: {failure['start']}")

        if failure.get('next_result', {}).get('error'):
            print(f"   get_next error: {failure['next_result']['error']}")
        elif failure.get('next_result', {}).get('differences'):
            diffs = failure['next_result']['differences']
            print(f"   get_next differences: {diffs[:2]}")

        if failure.get('prev_result', {}).get('error'):
            print(f"   get_prev error: {failure['prev_result']['error']}")
        elif failure.get('prev_result', {}).get('differences'):
            diffs = failure['prev_result']['differences']
            print(f"   get_prev differences: {diffs[:2]}")

        if not failure.get('match_result', {}).get('passed'):
            mr = failure['match_result']
            print(f"   match: py={mr.get('py_result')}, rs={mr.get('rs_result')}")


def compare_results(file1: str, file2: str):
    """Compare two result files."""
    with open(file1, 'r') as f:
        results1 = json.load(f)
    with open(file2, 'r') as f:
        results2 = json.load(f)

    print(f"{'='*80}")
    print(f"Comparison: {Path(file1).name} vs {Path(file2).name}")
    print(f"{'='*80}\n")

    total1 = results1['passed'] + results1['failed'] + results1['errors']
    total2 = results2['passed'] + results2['failed'] + results2['errors']

    print(f"File 1 ({Path(file1).name}):")
    print(f"  Total: {total1}, Passed: {results1['passed']}, Failed: {results1['failed']}, Errors: {results1['errors']}")

    print(f"\nFile 2 ({Path(file2).name}):")
    print(f"  Total: {total2}, Passed: {results2['passed']}, Failed: {results2['failed']}, Errors: {results2['errors']}")

    print(f"\nDifference:")
    print(f"  Passed: {results2['passed'] - results1['passed']:+d}")
    print(f"  Failed: {results2['failed'] - results1['failed']:+d}")
    print(f"  Errors: {results2['errors'] - results1['errors']:+d}")


def main():
    if len(sys.argv) < 2:
        print("Usage:")
        print("  python analyze_results.py <results.json>")
        print("  python analyze_results.py <results1.json> <results2.json>")
        sys.exit(1)

    if len(sys.argv) == 2:
        analyze_results(sys.argv[1])
    else:
        compare_results(sys.argv[1], sys.argv[2])


if __name__ == '__main__':
    main()
