"""Text parser for rocprof-sys text outputs.

Parses human-readable text files generated by rocprof-sys-run:
- wall-clock.txt - Wall clock timing summary
"""

import re
from pathlib import Path

from wafer_core.lib.rocprofiler.systems.types import SystemMetrics


def parse_text_summary(file_path: Path) -> tuple[list[SystemMetrics], dict]:
    """Parse wall-clock.txt or similar text summary files.

    Args:
        file_path: Path to text summary file

    Returns:
        Tuple of (metrics_list, summary_dict)
        - metrics_list: List of SystemMetrics parsed from table
        - summary_dict: Overall summary statistics
    """
    with open(file_path, "r") as f:
        content = f.read()

    metrics = []
    summary = {}

    # Parse line by line
    lines = content.split("\n")

    # Look for table headers and data rows
    # Common format:
    # Function Name          Count    Total Time    Mean Time    ...
    # -----------------      -----    ----------    ---------    ...
    # my_function            100      1.5 ms        15 us        ...

    in_table = False
    header_indices = {}

    for line in lines:
        line = line.strip()
        if not line:
            continue

        # Detect table headers
        if "function" in line.lower() or "name" in line.lower():
            # Parse header line to find column positions
            header_indices = _parse_header_line(line)
            in_table = True
            continue

        # Skip separator lines
        if re.match(r"^[-=]+$", line):
            continue

        # Parse data rows
        if in_table and header_indices:
            metric = _parse_data_row(line, header_indices)
            if metric:
                metrics.append(metric)

        # Parse summary statistics
        # Look for lines like "Total Time: 1.5 ms" or "Total Functions: 100"
        summary_match = re.match(
            r"^([\w\s]+):\s*([\d.]+)\s*(\w+)?$", line, re.IGNORECASE
        )
        if summary_match:
            key, value, unit = summary_match.groups()
            key = key.strip().lower().replace(" ", "_")
            try:
                value = float(value)
                if unit:
                    # Convert to standard units (nanoseconds for time)
                    value = _convert_unit(value, unit)
                summary[key] = value
            except ValueError:
                pass

    return metrics, summary


def _parse_header_line(line: str) -> dict[str, int]:
    """Parse table header line to find column positions.

    Args:
        line: Header line string

    Returns:
        Dictionary mapping column names to their start positions
    """
    indices = {}

    # Common column names
    columns = [
        "name",
        "function",
        "count",
        "calls",
        "total",
        "mean",
        "min",
        "max",
        "stddev",
        "cpu",
        "gpu",
    ]

    for col in columns:
        # Case-insensitive search
        pattern = re.compile(r"\b" + col + r"\b", re.IGNORECASE)
        match = pattern.search(line)
        if match:
            indices[col] = match.start()

    return indices


def _parse_data_row(line: str, header_indices: dict[str, int]) -> SystemMetrics | None:
    """Parse a data row using column positions from header.

    Args:
        line: Data row string
        header_indices: Column positions from header

    Returns:
        SystemMetrics object, or None if parsing fails
    """
    # This is a simplified parser - actual implementation would need
    # more robust column extraction based on positions

    # Split by whitespace and try to extract values
    parts = line.split()
    if len(parts) < 2:
        return None

    try:
        # First part is usually the function name
        function_name = parts[0]

        # Try to find numeric values
        numeric_values = []
        for part in parts[1:]:
            try:
                # Remove units and parse
                value_str = re.sub(r"[a-zA-Z]+$", "", part)
                numeric_values.append(float(value_str))
            except ValueError:
                continue

        if not numeric_values:
            return None

        # Map values to fields (heuristic-based)
        # Typical order: count, total, mean, min, max, stddev
        return SystemMetrics(
            function_name=function_name,
            call_count=int(numeric_values[0]) if len(numeric_values) > 0 else None,
            total_time_ns=numeric_values[1] if len(numeric_values) > 1 else None,
            mean_time_ns=numeric_values[2] if len(numeric_values) > 2 else None,
            min_time_ns=numeric_values[3] if len(numeric_values) > 3 else None,
            max_time_ns=numeric_values[4] if len(numeric_values) > 4 else None,
            stddev_ns=numeric_values[5] if len(numeric_values) > 5 else None,
        )
    except Exception:
        return None


def _convert_unit(value: float, unit: str) -> float:
    """Convert value with unit to standard unit (nanoseconds for time).

    Args:
        value: Numeric value
        unit: Unit string (ns, us, ms, s, etc.)

    Returns:
        Value in standard unit
    """
    unit = unit.lower().strip()

    # Time units
    if unit in ["ns", "nanoseconds"]:
        return value
    elif unit in ["us", "microseconds"]:
        return value * 1_000
    elif unit in ["ms", "milliseconds"]:
        return value * 1_000_000
    elif unit in ["s", "seconds"]:
        return value * 1_000_000_000

    # No conversion needed
    return value
