import json
import pytest
import datetime
import os
import time
from pathlib import Path

class JSONReporter:
    """
    Custom pytest plugin to generate JSON test reports.
    Based on the specification in section 9.4 of descripcion.md.
    """
    def __init__(self, config):
        self.config = config
        self.start_time = time.time()
        self.results = {
            'summary': {
                'total': 0,
                'passed': 0,
                'failed': 0,
                'skipped': 0,
                'error': 0,
                'duration': 0,
                'timestamp': datetime.datetime.now().isoformat()
            },
            'tests': []
        }
        
    def pytest_runtest_logreport(self, report):
        """Handle the reporting of a test run."""
        if report.when == 'call' or (report.when == 'setup' and report.skipped):
            self.results['summary']['total'] += 1
            
            if report.passed:
                result = 'passed'
                self.results['summary']['passed'] += 1
            elif report.failed:
                if report.when != 'call':
                    result = 'error'
                    self.results['summary']['error'] += 1
                else:
                    result = 'failed'
                    self.results['summary']['failed'] += 1
            elif report.skipped:
                result = 'skipped'
                self.results['summary']['skipped'] += 1
            
            # Extract test metadata
            test_module = report.nodeid.split('::')[0]
            test_class = report.nodeid.split('::')[1] if '::' in report.nodeid else None
            test_name = report.nodeid.split('::')[-1]
            
            # Extract error details if present
            error_message = None
            error_trace = None
            if hasattr(report, 'longrepr') and report.longrepr:
                if hasattr(report.longrepr, 'reprcrash') and report.longrepr.reprcrash:
                    error_message = report.longrepr.reprcrash.message
                error_trace = str(report.longrepr)
            
            # Add test result to list
            self.results['tests'].append({
                'id': report.nodeid,
                'module': test_module,
                'class': test_class,
                'name': test_name,
                'result': result,
                'duration': report.duration,
                'error_message': error_message,
                'error_trace': error_trace
            })
    
    def pytest_sessionfinish(self, session):
        """Generate report at end of test session."""
        self.results['summary']['duration'] = time.time() - self.start_time
        
        # Create output directory if it doesn't exist
        output_dir = Path('test_reports')
        output_dir.mkdir(exist_ok=True)
        
        # Generate timestamp for file name
        timestamp = datetime.datetime.now().strftime('%Y%m%d_%H%M%S')
        output_path = output_dir / f'test_results_{timestamp}.json'
        
        # Write results to file
        with open(output_path, 'w', encoding='utf-8') as f:
            json.dump(self.results, f, indent=2, ensure_ascii=False)
        
        # Also create a symlink/copy to latest results
        latest_path = output_dir / 'test_results_latest.json'
        if os.path.exists(latest_path):
            os.remove(latest_path)
        with open(latest_path, 'w', encoding='utf-8') as f:
            json.dump(self.results, f, indent=2, ensure_ascii=False)
            
        print(f"\nJSON test report generated: {output_path}")

@pytest.hookimpl(tryfirst=True)
def pytest_configure(config):
    """Register the JSON reporter plugin."""
    config.pluginmanager.register(JSONReporter(config), 'json_reporter')
