/**
 * @license
 * Copyright 2025 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */

import {zod} from '../third_party/index.js';
import type {ConsoleMessageType} from '../third_party/index.js';

import {ToolCategory} from './categories.js';
import {definePageTool} from './ToolDefinition.js';
type ConsoleResponseType = ConsoleMessageType | 'issue';

const FILTERABLE_MESSAGE_TYPES: [
  ConsoleResponseType,
  ...ConsoleResponseType[],
] = [
  'log',
  'debug',
  'info',
  'error',
  'warn',
  'dir',
  'dirxml',
  'table',
  'trace',
  'clear',
  'startGroup',
  'startGroupCollapsed',
  'endGroup',
  'assert',
  'profile',
  'profileEnd',
  'count',
  'timeEnd',
  'verbose',
  'issue',
];

const LIST_CONSOLE_MESSAGES_TOOL_NAME = 'list_console_messages';

export const listConsoleMessages = definePageTool(cliArgs => {
  return {
    name: LIST_CONSOLE_MESSAGES_TOOL_NAME,
    description: `List all console messages for the currently selected page since the last navigation.${cliArgs?.categoryExtensions ? ' This includes console messages originating from extensions content scripts.' : ''}`,
    annotations: {
      category: ToolCategory.DEBUGGING,
      readOnlyHint: true,
    },
    schema: {
      pageSize: zod
        .number()
        .int()
        .positive()
        .optional()
        .describe(
          'Maximum number of messages to return. When omitted, returns all messages.',
        ),
      pageIdx: zod
        .number()
        .int()
        .min(0)
        .optional()
        .describe(
          'Page number to return (0-based). When omitted, returns the first page.',
        ),
      types: zod
        .array(zod.enum(FILTERABLE_MESSAGE_TYPES))
        .optional()
        .describe(
          'Filter messages to only return messages of the specified resource types. When omitted or empty, returns all messages.',
        ),
      includePreservedMessages: zod
        .boolean()
        .default(false)
        .optional()
        .describe(
          'Set to true to return the preserved messages over the last 3 navigations.',
        ),
      serviceWorkerId: zod
        .string()
        .optional()
        .describe(
          'Filter messages to only return messages of the specified service worker.',
        ),
    },
    blockedByDialog: false,
    verifyFilesSchema: [],
    handler: async (request, response) => {
      response.setIncludeConsoleData(true, {
        pageSize: request.params.pageSize,
        pageIdx: request.params.pageIdx,
        types: request.params.types,
        includePreservedMessages: request.params.includePreservedMessages,
        serviceWorkerId: request.params.serviceWorkerId,
      });
    },
  };
});

export const getConsoleMessage = definePageTool({
  name: 'get_console_message',
  description: `Gets a console message by its ID. You can get all messages by calling ${LIST_CONSOLE_MESSAGES_TOOL_NAME}.`,
  annotations: {
    category: ToolCategory.DEBUGGING,
    readOnlyHint: true,
  },
  schema: {
    msgid: zod
      .number()
      .describe(
        'The msgid of a console message on the page from the listed console messages',
      ),
  },
  blockedByDialog: false,
  verifyFilesSchema: [],
  handler: async (request, response) => {
    response.attachConsoleMessage(request.params.msgid);
  },
});
