import { statSync } from "node:fs";
import { readFile } from "node:fs/promises";
import { type ParsedCommand, parseCommandXml } from "../parseCommandXml";
import { parseJsonl } from "../parseJsonl";
import type { SessionMeta } from "../types";

const firstCommandCache = new Map<string, ParsedCommand | null>();

const ignoreCommands = [
  "/clear",
  "/login",
  "/logout",
  "/exit",
  "/mcp",
  "/memory",
];

const getFirstCommand = (
  jsonlFilePath: string,
  lines: string[],
): ParsedCommand | null => {
  const cached = firstCommandCache.get(jsonlFilePath);
  if (cached !== undefined) {
    return cached;
  }

  let firstCommand: ParsedCommand | null = null;

  for (const line of lines) {
    const conversation = parseJsonl(line).at(0);

    if (conversation === undefined || conversation.type !== "user") {
      continue;
    }

    const firstUserText =
      conversation === null
        ? null
        : typeof conversation.message.content === "string"
          ? conversation.message.content
          : (() => {
              const firstContent = conversation.message.content.at(0);
              if (firstContent === undefined) return null;
              if (typeof firstContent === "string") return firstContent;
              if (firstContent.type === "text") return firstContent.text;
              return null;
            })();

    if (firstUserText === null) {
      continue;
    }

    if (
      firstUserText ===
      "Caveat: The messages below were generated by the user while running local commands. DO NOT respond to these messages or otherwise consider them in your response unless the user explicitly asks you to."
    ) {
      continue;
    }

    const command = parseCommandXml(firstUserText);
    if (command.kind === "local-command") {
      continue;
    }

    if (
      command.kind === "command" &&
      ignoreCommands.includes(command.commandName)
    ) {
      continue;
    }

    firstCommand = command;
    break;
  }

  if (firstCommand !== null) {
    firstCommandCache.set(jsonlFilePath, firstCommand);
  }

  return firstCommand;
};

export const getSessionMeta = async (
  jsonlFilePath: string,
): Promise<SessionMeta> => {
  const stats = statSync(jsonlFilePath);
  const lastModifiedUnixTime = stats.ctime.getTime();

  const content = await readFile(jsonlFilePath, "utf-8");
  const lines = content.split("\n");

  const sessionMeta: SessionMeta = {
    messageCount: lines.length,
    firstCommand: getFirstCommand(jsonlFilePath, lines),
    lastModifiedAt: lastModifiedUnixTime
      ? new Date(lastModifiedUnixTime).toISOString()
      : null,
  };

  return sessionMeta;
};
