/**
 * 任务日志解析与分组工具函数。
 *
 * 解析 TaskLogBuffer 输出的日志格式：[TASK_CODE] timestamp level message
 * 将扁平日志行按任务代码分组，提取时间线信息。
 */

/** 单条解析后的日志条目 */
export interface ParsedLogEntry {
  /** 原始行文本 */
  raw: string;
  /** 任务代码（如 ODS_MEMBER） */
  taskCode: string;
  /** 时间戳字符串（原始格式） */
  timestamp: string;
  /** 日志级别：INFO / WARNING / ERROR / DEBUG */
  level: string;
  /** 日志消息正文 */
  message: string;
}

/** 按任务分组后的日志集合 */
export interface TaskLogGroup {
  taskCode: string;
  entries: ParsedLogEntry[];
  /** 该任务第一条日志的时间戳 */
  startTime: string | null;
  /** 该任务最后一条日志的时间戳 */
  endTime: string | null;
  /** 推断的任务状态：success / failed / running / unknown */
  status: "success" | "failed" | "running" | "unknown";
  /** 各级别日志计数 */
  counts: { info: number; warning: number; error: number; debug: number };
}

/**
 * 匹配 TaskLogBuffer 输出格式：[TASK_CODE] 2024-01-01 12:00:00 INFO 消息内容
 * 也兼容：[TASK_CODE] 2024-01-01 12:00:00,123 INFO 消息内容
 */
const LOG_LINE_REGEX =
  /^\[([A-Z][A-Z0-9_]*)\]\s+(\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2}(?:[.,]\d+)?)\s+(DEBUG|INFO|WARNING|ERROR|CRITICAL)\s+(.*)$/;

/**
 * 解析单行日志。无法解析时返回 null。
 */
export function parseLogLine(line: string): ParsedLogEntry | null {
  const match = LOG_LINE_REGEX.exec(line.trim());
  if (!match) return null;
  return {
    raw: line,
    taskCode: match[1],
    timestamp: match[2],
    level: match[3],
    message: match[4],
  };
}

/**
 * 将日志行数组按任务代码分组。
 * 无法解析的行归入 "_UNKNOWN" 分组。
 */
export function groupLogsByTask(lines: string[]): TaskLogGroup[] {
  const groupMap = new Map<string, ParsedLogEntry[]>();

  for (const line of lines) {
    if (!line.trim()) continue;
    const parsed = parseLogLine(line);
    const code = parsed?.taskCode ?? "_UNKNOWN";
    const entry: ParsedLogEntry = parsed ?? {
      raw: line,
      taskCode: "_UNKNOWN",
      timestamp: "",
      level: "INFO",
      message: line,
    };
    const arr = groupMap.get(code);
    if (arr) {
      arr.push(entry);
    } else {
      groupMap.set(code, [entry]);
    }
  }

  const groups: TaskLogGroup[] = [];
  for (const [taskCode, entries] of groupMap) {
    const counts = { info: 0, warning: 0, error: 0, debug: 0 };
    for (const e of entries) {
      const lvl = e.level.toLowerCase();
      if (lvl === "info") counts.info++;
      else if (lvl === "warning" || lvl === "critical") counts.warning++;
      else if (lvl === "error") counts.error++;
      else if (lvl === "debug") counts.debug++;
    }

    // 推断状态：有 ERROR 级别 → failed；否则看最后一条消息
    let status: TaskLogGroup["status"] = "unknown";
    if (counts.error > 0) {
      status = "failed";
    } else if (entries.length > 0) {
      const lastMsg = entries[entries.length - 1].message.toLowerCase();
      if (lastMsg.includes("完成") || lastMsg.includes("success") || lastMsg.includes("finished")) {
        status = "success";
      }
    }

    const timestamps = entries.map((e) => e.timestamp).filter(Boolean);
    groups.push({
      taskCode,
      entries,
      startTime: timestamps[0] ?? null,
      endTime: timestamps.length > 0 ? timestamps[timestamps.length - 1] : null,
      status,
      counts,
    });
  }

  return groups;
}

/**
 * 按任务代码过滤分组。空关键词返回全部。
 */
export function filterTaskGroups(
  groups: TaskLogGroup[],
  keyword: string,
): TaskLogGroup[] {
  const kw = keyword.trim().toUpperCase();
  if (!kw) return groups;
  return groups.filter((g) => g.taskCode.toUpperCase().includes(kw));
}
