/**
 * 任务日志解析与分组测试
 *
 * **Validates: Requirements 10.2, 10.5, 10.6**
 *
 * 验证 parseLogLine / groupLogsByTask / filterTaskGroups 的正确性。
 */

import { describe, it, expect } from "vitest";
import {
  parseLogLine,
  groupLogsByTask,
  filterTaskGroups,
} from "../utils/taskLogParser";

/* ------------------------------------------------------------------ */
/*  parseLogLine                                                       */
/* ------------------------------------------------------------------ */

describe("parseLogLine — 单行日志解析", () => {
  it("解析标准格式日志行", () => {
    const line = "[ODS_MEMBER] 2024-06-01 12:00:00 INFO 开始拉取会员数据";
    const result = parseLogLine(line);
    expect(result).not.toBeNull();
    expect(result!.taskCode).toBe("ODS_MEMBER");
    expect(result!.timestamp).toBe("2024-06-01 12:00:00");
    expect(result!.level).toBe("INFO");
    expect(result!.message).toBe("开始拉取会员数据");
  });

  it("解析带毫秒的时间戳", () => {
    const line = "[ODS_ORDER] 2024-06-01 12:00:00,123 ERROR 请求失败";
    const result = parseLogLine(line);
    expect(result).not.toBeNull();
    expect(result!.taskCode).toBe("ODS_ORDER");
    expect(result!.timestamp).toBe("2024-06-01 12:00:00,123");
    expect(result!.level).toBe("ERROR");
  });

  it("解析 WARNING 级别", () => {
    const line = "[DWD_LOAD_FROM_ODS] 2024-06-01 12:00:00 WARNING 队列积压";
    const result = parseLogLine(line);
    expect(result).not.toBeNull();
    expect(result!.level).toBe("WARNING");
  });

  it("解析 DEBUG 级别", () => {
    const line = "[ODS_MEMBER] 2024-06-01 12:00:00 DEBUG 调试信息";
    const result = parseLogLine(line);
    expect(result).not.toBeNull();
    expect(result!.level).toBe("DEBUG");
  });

  it("无法解析的行返回 null", () => {
    expect(parseLogLine("这是一行普通文本")).toBeNull();
    expect(parseLogLine("")).toBeNull();
    expect(parseLogLine("[lowercase] 2024-06-01 12:00:00 INFO msg")).toBeNull();
  });
});

/* ------------------------------------------------------------------ */
/*  groupLogsByTask                                                    */
/* ------------------------------------------------------------------ */

describe("groupLogsByTask — 按任务分组", () => {
  const sampleLines = [
    "[ODS_MEMBER] 2024-06-01 12:00:00 INFO 开始拉取",
    "[ODS_MEMBER] 2024-06-01 12:00:05 INFO 拉取完成",
    "[ODS_ORDER] 2024-06-01 12:00:10 INFO 开始拉取订单",
    "[ODS_ORDER] 2024-06-01 12:00:20 ERROR 请求超时",
    "[ODS_MEMBER] 2024-06-01 12:00:25 INFO 写入完成 success",
  ];

  it("正确分组到不同任务", () => {
    const groups = groupLogsByTask(sampleLines);
    expect(groups).toHaveLength(2);
    const memberGroup = groups.find((g) => g.taskCode === "ODS_MEMBER");
    const orderGroup = groups.find((g) => g.taskCode === "ODS_ORDER");
    expect(memberGroup).toBeDefined();
    expect(orderGroup).toBeDefined();
    expect(memberGroup!.entries).toHaveLength(3);
    expect(orderGroup!.entries).toHaveLength(2);
  });

  it("提取正确的开始/结束时间", () => {
    const groups = groupLogsByTask(sampleLines);
    const memberGroup = groups.find((g) => g.taskCode === "ODS_MEMBER")!;
    expect(memberGroup.startTime).toBe("2024-06-01 12:00:00");
    expect(memberGroup.endTime).toBe("2024-06-01 12:00:25");
  });

  it("有 ERROR 的任务状态为 failed", () => {
    const groups = groupLogsByTask(sampleLines);
    const orderGroup = groups.find((g) => g.taskCode === "ODS_ORDER")!;
    expect(orderGroup.status).toBe("failed");
    expect(orderGroup.counts.error).toBe(1);
  });

  it("最后一条含 success 的任务状态为 success", () => {
    const groups = groupLogsByTask(sampleLines);
    const memberGroup = groups.find((g) => g.taskCode === "ODS_MEMBER")!;
    expect(memberGroup.status).toBe("success");
  });

  it("空行被忽略", () => {
    const groups = groupLogsByTask(["", "  ", "[ODS_A] 2024-01-01 00:00:00 INFO ok"]);
    expect(groups).toHaveLength(1);
    expect(groups[0].taskCode).toBe("ODS_A");
  });

  it("无法解析的行归入 _UNKNOWN", () => {
    const groups = groupLogsByTask(["普通文本行", "另一行"]);
    expect(groups).toHaveLength(1);
    expect(groups[0].taskCode).toBe("_UNKNOWN");
    expect(groups[0].entries).toHaveLength(2);
  });

  it("空数组返回空分组", () => {
    expect(groupLogsByTask([])).toEqual([]);
  });

  it("日志计数正确", () => {
    const lines = [
      "[T1] 2024-01-01 00:00:00 INFO a",
      "[T1] 2024-01-01 00:00:01 WARNING b",
      "[T1] 2024-01-01 00:00:02 ERROR c",
      "[T1] 2024-01-01 00:00:03 DEBUG d",
      "[T1] 2024-01-01 00:00:04 INFO e",
    ];
    const groups = groupLogsByTask(lines);
    expect(groups[0].counts).toEqual({ info: 2, warning: 1, error: 1, debug: 1 });
  });
});

/* ------------------------------------------------------------------ */
/*  filterTaskGroups                                                   */
/* ------------------------------------------------------------------ */

describe("filterTaskGroups — 按任务代码过滤", () => {
  const lines = [
    "[ODS_MEMBER] 2024-06-01 12:00:00 INFO a",
    "[ODS_ORDER] 2024-06-01 12:00:01 INFO b",
    "[DWD_LOAD_FROM_ODS] 2024-06-01 12:00:02 INFO c",
  ];

  it("空关键词返回全部", () => {
    const groups = groupLogsByTask(lines);
    expect(filterTaskGroups(groups, "")).toHaveLength(3);
    expect(filterTaskGroups(groups, "  ")).toHaveLength(3);
  });

  it("精确匹配任务代码", () => {
    const groups = groupLogsByTask(lines);
    const filtered = filterTaskGroups(groups, "ODS_MEMBER");
    expect(filtered).toHaveLength(1);
    expect(filtered[0].taskCode).toBe("ODS_MEMBER");
  });

  it("部分匹配（大小写不敏感）", () => {
    const groups = groupLogsByTask(lines);
    const filtered = filterTaskGroups(groups, "ods");
    // "ODS_MEMBER", "ODS_ORDER", "DWD_LOAD_FROM_ODS" 都包含 "ods"
    expect(filtered).toHaveLength(3);
  });

  it("无匹配返回空数组", () => {
    const groups = groupLogsByTask(lines);
    expect(filterTaskGroups(groups, "NONEXISTENT")).toEqual([]);
  });
});
