import csv
import logging
import statistics
from dataclasses import dataclass
from pathlib import Path

from test_automation_suite.templates import render_and_write_template

logger = logging.getLogger(__name__)

""" 
MangoHud successfully logs FPS data but does not report NVIDIA GPU metrics
(power, utilization, temperature) on the tested system.

The issue was reproduced with any and multiple MangoHud configurations,
including NVML-related options. NVIDIA GPU detection appears to work
(the GPU name is shown), but GPU telemetry values are not written to the log.

The exact cause is currently unknown. Possible factors include:
- MangoHud/NVIDIA integration issues
- Wayland-specific limitations
- Distribution packaging/version differences
- Missing or incompatible NVML/XNVCtrl support

Related reports:
https://github.com/flightlessmango/MangoHud/issues/859
https://forum.endeavouros.com/t/mangohud-shows-0-gpu-utilization/68194/11

In conclusion for the time being, only the fps data will be extracted 
and for the future cpu data if needed.
"""


@dataclass
class MangoHudStatistics:
    fps_values: list[float]
    fps_avg: float
    fps_median: float
    fps_min: float
    fps_max: float
    fps_1_percent_low: float


mangohud_config_dir = Path.home() / ".config" / "MangoHud"


class MangoHud:
    logging_dir: Path

    def __init__(self, logging_dir: Path) -> None:
        self.logging_dir = logging_dir
        self.logging_dir.mkdir(parents=True, exist_ok=True)
        self._create_config()

    def _create_config(self) -> None:
        mangohud_config_dir.mkdir(parents=True, exist_ok=True)

        config_file = mangohud_config_dir / "MangoHud.conf"

        _ = render_and_write_template(
            "MangoHud.conf",
            config_file,
            {
                "mangohud_logging_dir": self.logging_dir,
            },
        )

        logger.debug(f"Created Mangohud config at {config_file}")

    def _get_latest_log(self) -> Path:
        """Returns the path to the newest MangoHud log

        Mangohud currently hast no way of specifiying the name of the log file.
        It allways calls them `[program name]_[time stamp].csv`.
        """
        logs = sorted(self.logging_dir.iterdir())
        if not logs:
            raise FileNotFoundError("No MangoHud log found.")

        return logs[-1]

    def calculate_fps_statistics(self) -> MangoHudStatistics:
        log_file = self._get_latest_log()
        fps_values: list[float] = []

        with open(log_file, newline="") as file:
            # skips the first two lines, which contain
            # 1. csv headers for system info
            # 2. csv row for system info
            for line in file:
                if line.startswith("fps"):
                    header = line
                    break
            else:
                raise ValueError(f"No MangoHud FPS header found in {log_file}")

            reader = csv.DictReader(file, fieldnames=header.strip().split(","))

            for row in reader:
                value = row.get("fps")
                if not value:
                    continue

                fps_values.append(float(value))

        if not fps_values:
            raise ValueError(f"No FPS values found in {log_file}")

        sorted_fps = sorted(fps_values)
        index_1_percent = max(0, int(len(sorted_fps) * 0.01) - 1)

        return MangoHudStatistics(
            fps_values=fps_values,
            fps_avg=statistics.mean(fps_values),
            fps_median=statistics.median(fps_values),
            fps_min=min(fps_values),
            fps_max=max(fps_values),
            fps_1_percent_low=sorted_fps[index_1_percent],
        )
