#!/usr/bin/env python3
"""
Simple Python wrapper for Google Elo C++ implementation.
"""

import subprocess
import tempfile
import os
import pandas as pd
import re
from pathlib import Path
import time
import sys

# Add parent directory to path to import config
sys.path.append(str(Path(__file__).parent.parent))
from config import SCRATCH_TEMP_DIRECTORY

class GoogleEloWrapper:
    """Simple wrapper for Google Elo C++ implementation."""
    
    def __init__(self):
        """Initialize the wrapper."""
        script_dir = Path(__file__).parent
        self.elo_binary_path = script_dir / "google_elo" / "build" / "elo_main"
    
    def run_elo_analysis(self, df: pd.DataFrame) -> pd.DataFrame:
        """Run Google Elo analysis on a DataFrame.
        
        Args:
            df: DataFrame in Google Elo format (methodA, methodB, answerValue, answerer)
            
        Returns:
            DataFrame with ELO scores and confidence intervals
        """
        
        # Create temporary CSV file
        temp_dir = SCRATCH_TEMP_DIRECTORY
        os.makedirs(temp_dir, exist_ok=True)
        
        with tempfile.NamedTemporaryFile(mode='w', suffix='.csv', delete=False, dir=temp_dir) as f:

            # if isGolden is True, change it to true
            df['isGolden'] = df['isGolden'].astype(str).replace('True', 'true')
            # in first two columns if they are empty then insert N/A
            df['methodA'] = df['methodA'].fillna('N/A')
            df['methodB'] = df['methodB'].fillna('N/A')
            df.to_csv(f, index=False, header=True)
            temp_csv_path = f.name
        
        try:
            # Run the elo binary
            # change True to true in isGolden column
            df['isGolden'] = df['isGolden'].astype(str).replace('True', 'true')
            start = time.time()
            result = subprocess.run(
                [str(self.elo_binary_path), f"--csv_path={temp_csv_path}"],
                capture_output=True,
                text=True,
                check=True
            )
            end = time.time()
            delta_time = end - start

            # Parse the output and return DataFrame
            return self._parse_elo_output(result.stdout), delta_time
            
        except subprocess.CalledProcessError as e:
            print(f"Error running Google Elo: {e}")
            print(f"stdout: {e.stdout}")
            print(f"stderr: {e.stderr}")
            return pd.DataFrame(), 0
        
        finally:
            # Clean up temporary file
            pass
    
    def _parse_elo_output(self, output: str) -> pd.DataFrame:
        """Parse the output from the Google Elo binary and return a DataFrame.
        
        Args:
            output: Raw output from the elo binary
            
        Returns:
            DataFrame with ELO scores
        """
        lines = output.strip().split('\n')
        
        elo_scores = []
        
        for line in lines:
            line = line.strip()

            # Stop at empty lines or section headers
            if len(line) == 0:
                break
                
            # take the part until : as the method and between : and [ as the elo score
            method = line.split(":")[0].strip()
            if len(method) == 0:
                continue
            score = line.split(":")[1].split("[")[0]
            low = line.split("[")[1].split("-")[0].strip()
            high = line.split("[")[1].split("-")[1].split("]")[0].strip()
            elo_scores.append({
                'Method': method,
                'ELO Score': float(score),
                'Lower CI (99%)': float(low),
                'Upper CI (99%)': float(high)
            })
        
        df = pd.DataFrame(elo_scores)
        return df.sort_values('ELO Score', ascending=False).reset_index(drop=True)

