package com.openosrs.client.plugins.examples;

import com.openosrs.client.plugins.*;
import com.openosrs.client.api.*;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Performance monitor plugin that tracks FPS and other metrics.
 */
public class PerformanceMonitorPlugin extends AbstractPlugin {
    private final Map<String, Double> metrics = new ConcurrentHashMap<>();
    private volatile boolean monitoring = false;
    private Thread monitorThread;
    private long lastFrameTime = 0;
    private int frameCount = 0;
    
    @Override
    protected void enable() {
        logger.info("Performance monitor plugin enabled");
        
        monitoring = true;
        monitorThread = new Thread(this::monitorPerformance);
        monitorThread.setDaemon(true);
        monitorThread.start();
        
        // Listen for frame events
        addEventListener("FRAME_RENDERED", this::onFrameRendered);
    }
    
    @Override
    protected void disable() {
        logger.info("Performance monitor plugin disabled");
        
        monitoring = false;
        if (monitorThread != null) {
            monitorThread.interrupt();
        }
    }
    
    private void monitorPerformance() {
        while (monitoring && !Thread.currentThread().isInterrupted()) {
            try {
                updateMetrics();
                logPerformanceReport();
                
                Thread.sleep(5000); // Report every 5 seconds
                
            } catch (InterruptedException e) {
                break;
            } catch (Exception e) {
                logger.error("Error in performance monitoring", e);
            }
        }
    }
    
    private void updateMetrics() {
        Runtime runtime = Runtime.getRuntime();
        
        // Memory metrics
        long totalMemory = runtime.totalMemory();
        long freeMemory = runtime.freeMemory();
        long usedMemory = totalMemory - freeMemory;
        long maxMemory = runtime.maxMemory();
        
        metrics.put("memory.used.mb", usedMemory / (1024.0 * 1024.0));
        metrics.put("memory.total.mb", totalMemory / (1024.0 * 1024.0));
        metrics.put("memory.max.mb", maxMemory / (1024.0 * 1024.0));
        metrics.put("memory.usage.percent", (usedMemory * 100.0) / totalMemory);
        
        // CPU metrics (simplified)
        metrics.put("cpu.processors", (double) runtime.availableProcessors());
    }
    
    private void onFrameRendered(Object eventData) {
        frameCount++;
        long currentTime = System.currentTimeMillis();
        
        if (lastFrameTime == 0) {
            lastFrameTime = currentTime;
            return;
        }
        
        long elapsed = currentTime - lastFrameTime;
        if (elapsed >= 1000) { // Calculate FPS every second
            double fps = (frameCount * 1000.0) / elapsed;
            metrics.put("rendering.fps", fps);
            
            frameCount = 0;
            lastFrameTime = currentTime;
        }
    }
    
    private void logPerformanceReport() {
        StringBuilder report = new StringBuilder();
        report.append("Performance Report:\\n");
        
        for (Map.Entry<String, Double> entry : metrics.entrySet()) {
            report.append(String.format("  %s: %.2f\\n", entry.getKey(), entry.getValue()));
        }
        
        logger.debug(report.toString());
    }
    
    public Map<String, Double> getMetrics() {
        return new ConcurrentHashMap<>(metrics);
    }
    
    @Override
    public PluginMetadata getMetadata() {
        return new PluginMetadata(
            "Performance Monitor",
            "Monitors client performance metrics",
            "OpenOSRS Agent",
            "1.0",
            new ArrayList<>(),
            Arrays.asList("monitoring", "performance", "debugging")
        );
    }
}