/**
 * Line Profiler Parser Utility
 * Parses the markdown table output from Python's line_profiler into structured data
 */

export interface LineProfilerEntry {
  hits: string;
  time: string;
  perHit: string;
  percentTime: number;
  lineContents: string;
}

export interface LineProfilerFunction {
  functionName: string;
  totalTime: string;
  entries: LineProfilerEntry[];
}

export interface LineProfilerReport {
  timerUnit: string;
  functions: LineProfilerFunction[];
}

/**
 * Parse line profiler results from the markdown table format
 * Expected format:
 * ```
 * # Timer unit: 1e-09 s
 * ## Function: function_name
 * ## Total time: X s
 * | Hits | Time | Per Hit | % Time | Line Contents |
 * |------|------|---------|--------|---------------|
 * | 123  | 456  | 3.7     | 50.0   | def foo():   |
 * ```
 */
export function parseLineProfilerResults(rawResults: string): LineProfilerReport {
  const report: LineProfilerReport = {
    timerUnit: "",
    functions: [],
  };

  if (!rawResults || rawResults.trim() === "") {
    return report;
  }

  const lines = rawResults.split("\n");
  let currentFunction: LineProfilerFunction | null = null;
  let inTable = false;
  let headerPassed = false;

  for (const line of lines) {
    const trimmedLine = line.trim();

    // Parse timer unit
    if (trimmedLine.startsWith("# Timer unit:")) {
      report.timerUnit = trimmedLine.replace("# Timer unit:", "").trim();
      continue;
    }

    // Parse function name
    if (trimmedLine.startsWith("## Function:")) {
      if (currentFunction) {
        report.functions.push(currentFunction);
      }
      currentFunction = {
        functionName: trimmedLine.replace("## Function:", "").trim(),
        totalTime: "",
        entries: [],
      };
      inTable = false;
      headerPassed = false;
      continue;
    }

    // Parse total time
    if (trimmedLine.startsWith("## Total time:")) {
      if (currentFunction) {
        currentFunction.totalTime = trimmedLine.replace("## Total time:", "").trim();
      }
      continue;
    }

    // Detect table header
    if (trimmedLine.includes("| Hits") && trimmedLine.includes("Line Contents")) {
      inTable = true;
      headerPassed = false;
      continue;
    }

    // Skip separator line (|---|---|...)
    if (inTable && trimmedLine.match(/^\|[-\s|]+\|$/)) {
      headerPassed = true;
      continue;
    }

    // Parse table rows
    if (inTable && headerPassed && trimmedLine.startsWith("|") && currentFunction) {
      const parts = trimmedLine
        .split("|")
        .map((p) => p.trim())
        .filter((p) => p !== "");

      if (parts.length >= 5) {
        const percentStr = parts[3] || "0";
        const percentTime = parseFloat(percentStr) || 0;

        currentFunction.entries.push({
          hits: parts[0] || "",
          time: parts[1] || "",
          perHit: parts[2] || "",
          percentTime,
          lineContents: parts.slice(4).join("|"), // Line contents may contain pipes
        });
      }
    }
  }

  // Don't forget the last function
  if (currentFunction) {
    report.functions.push(currentFunction);
  }

  return report;
}

/**
 * Get the heat level for a given percent time
 * Returns a class suffix for CSS styling
 */
export function getHeatLevel(percentTime: number): string {
  if (percentTime >= 50) {return "hot-4";}
  if (percentTime >= 30) {return "hot-3";}
  if (percentTime >= 15) {return "hot-2";}
  if (percentTime >= 5) {return "hot-1";}
  return "cold";
}

/**
 * Calculate the maximum percent time across all entries for normalization
 */
export function getMaxPercentTime(report: LineProfilerReport): number {
  let max = 0;
  for (const func of report.functions) {
    for (const entry of func.entries) {
      if (entry.percentTime > max) {
        max = entry.percentTime;
      }
    }
  }
  return max || 100;
}
