/**
 * @license
 * Copyright 2025 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import path from 'node:path';
import { snapshot, navigation, generateReport, zod, } from '../third_party/index.js';
import { ToolCategory } from './categories.js';
import { startTrace } from './performance.js';
import { definePageTool } from './ToolDefinition.js';
export const lighthouseAudit = definePageTool({
    name: 'lighthouse_audit',
    description: `Get Lighthouse score and reports for accessibility, SEO, best practices, and agentic browsing. This excludes performance. For performance audits, run ${startTrace.name}`,
    annotations: {
        category: ToolCategory.DEBUGGING,
        readOnlyHint: false,
    },
    schema: {
        mode: zod
            .enum(['navigation', 'snapshot'])
            .default('navigation')
            .describe('"navigation" reloads & audits. "snapshot" analyzes current state.'),
        device: zod
            .enum(['desktop', 'mobile'])
            .default('desktop')
            .describe('Device to emulate.'),
        outputDirPath: zod
            .string()
            .optional()
            .describe('Directory for reports. If omitted, uses temporary files.'),
    },
    blockedByDialog: true,
    verifyFilesSchema: ['outputDirPath'],
    handler: async (request, response, context) => {
        const page = request.page;
        const categories = [
            'accessibility',
            'seo',
            'best-practices',
            'agentic-browsing',
        ];
        const formats = ['json', 'html'];
        const { mode = 'navigation', device = 'desktop', outputDirPath, } = request.params;
        const flags = {
            onlyCategories: categories,
            output: formats,
            // Default 30 second timeout for page load.
            maxWaitForLoad: 30_000,
        };
        if (device === 'desktop') {
            flags.formFactor = 'desktop';
            flags.screenEmulation = {
                mobile: false,
                width: 1350,
                height: 940,
                deviceScaleFactor: 1,
                disabled: false,
            };
        }
        else {
            flags.formFactor = 'mobile';
            flags.screenEmulation = {
                mobile: true,
                width: 412,
                height: 823,
                deviceScaleFactor: 1.75,
                disabled: false,
            };
        }
        let result;
        try {
            if (mode === 'navigation') {
                result = await navigation(page.pptrPage, page.pptrPage.url(), {
                    flags,
                });
            }
            else {
                result = await snapshot(page.pptrPage, {
                    flags,
                });
            }
            if (!result) {
                throw new Error('Lighthouse audit failed.');
            }
        }
        finally {
            await context.restoreEmulation(page);
        }
        const lhr = result.lhr;
        const reportPaths = [];
        const encoder = new TextEncoder();
        const savePromises = formats.map(async (format) => {
            const report = generateReport(lhr, format);
            const data = encoder.encode(report);
            if (outputDirPath) {
                const reportPath = path.join(outputDirPath, `report`);
                const { filename } = await context.saveFile(data, reportPath, `.${format}`);
                return filename;
            }
            const { filepath } = await context.saveTemporaryFile(data, `report.${format}`);
            return filepath;
        });
        const results = await Promise.allSettled(savePromises);
        for (const res of results) {
            if (res.status === 'rejected') {
                throw res.reason;
            }
            reportPaths.push(res.value);
        }
        const categoryScores = Object.values(lhr.categories).map(c => ({
            id: c.id,
            title: c.title,
            score: c.score,
        }));
        const failedAudits = Object.values(lhr.audits).filter(a => a.score !== null && a.score < 1).length;
        const passedAudits = Object.values(lhr.audits).filter(a => a.score === 1).length;
        const output = {
            summary: {
                mode,
                device,
                url: lhr.mainDocumentUrl,
                scores: categoryScores,
                audits: {
                    failed: failedAudits,
                    passed: passedAudits,
                },
                timing: {
                    total: lhr.timing.total,
                },
            },
            reports: reportPaths,
        };
        response.attachLighthouseResult(output);
    },
});
//# sourceMappingURL=lighthouse.js.map