/**
 * @license
 * Copyright 2025 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import { BaseDeclarativeTool, BaseToolInvocation, Kind, } from './tools.js';
import { GET_INTERNAL_DOCS_TOOL_NAME } from './tool-names.js';
import fs from 'node:fs/promises';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { glob } from 'glob';
import { ToolErrorType } from './tool-error.js';
import { GET_INTERNAL_DOCS_DEFINITION } from './definitions/coreTools.js';
import { resolveToolDeclaration } from './definitions/resolver.js';
/**
 * Helper to find the absolute path to the documentation directory.
 */
async function getDocsRoot() {
    const currentFile = fileURLToPath(import.meta.url);
    let searchDir = path.dirname(currentFile);
    const isDocsDir = async (dir) => {
        try {
            const stats = await fs.stat(dir);
            if (stats.isDirectory()) {
                const marker = path.join(dir, 'sidebar.json');
                await fs.access(marker);
                return true;
            }
        }
        catch {
            // Not a valid docs directory
        }
        return false;
    };
    while (true) {
        const candidate = path.join(searchDir, 'docs');
        if (await isDocsDir(candidate)) {
            return candidate;
        }
        const parent = path.dirname(searchDir);
        if (parent === searchDir) {
            break;
        }
        searchDir = parent;
    }
    throw new Error('Could not find Gemini CLI documentation directory.');
}
class GetInternalDocsInvocation extends BaseToolInvocation {
    constructor(params, messageBus, _toolName, _toolDisplayName) {
        super(params, messageBus, _toolName, _toolDisplayName);
    }
    async shouldConfirmExecute(_abortSignal) {
        return false;
    }
    getDescription() {
        if (this.params.path) {
            return `Reading internal documentation: ${this.params.path}`;
        }
        return 'Listing all available internal documentation.';
    }
    async execute({ abortSignal: _signal }) {
        try {
            const docsRoot = await getDocsRoot();
            if (!this.params.path) {
                // List all .md files recursively
                const files = await glob('**/*.md', { cwd: docsRoot, posix: true });
                files.sort();
                const fileList = files.map((f) => `- ${f}`).join('\n');
                const resultContent = `Available Gemini CLI documentation files:\n\n${fileList}`;
                return {
                    llmContent: resultContent,
                    returnDisplay: `Found ${files.length} documentation files.`,
                };
            }
            // Read a specific file
            // Security: Prevent path traversal by resolving and verifying it stays within docsRoot
            const resolvedPath = path.resolve(docsRoot, this.params.path);
            if (!resolvedPath.startsWith(docsRoot)) {
                throw new Error('Access denied: Requested path is outside the documentation directory.');
            }
            const content = await fs.readFile(resolvedPath, 'utf8');
            return {
                llmContent: content,
                returnDisplay: `Successfully read documentation: ${this.params.path}`,
            };
        }
        catch (error) {
            const errorMessage = error instanceof Error ? error.message : String(error);
            return {
                llmContent: `Error accessing internal documentation: ${errorMessage}`,
                returnDisplay: `Failed to access documentation: ${errorMessage}`,
                error: {
                    message: errorMessage,
                    type: ToolErrorType.EXECUTION_FAILED,
                },
            };
        }
    }
}
/**
 * A tool that provides access to Gemini CLI's internal documentation.
 * If no path is provided, it returns a list of all available documentation files.
 * If a path is provided, it returns the content of that specific file.
 */
export class GetInternalDocsTool extends BaseDeclarativeTool {
    static Name = GET_INTERNAL_DOCS_TOOL_NAME;
    constructor(messageBus) {
        super(GetInternalDocsTool.Name, 'GetInternalDocs', GET_INTERNAL_DOCS_DEFINITION.base.description, Kind.Think, GET_INTERNAL_DOCS_DEFINITION.base.parametersJsonSchema, messageBus, 
        /* isOutputMarkdown */ true, 
        /* canUpdateOutput */ false);
    }
    createInvocation(params, messageBus, _toolName, _toolDisplayName) {
        return new GetInternalDocsInvocation(params, messageBus, _toolName ?? GetInternalDocsTool.Name, _toolDisplayName);
    }
    getSchema(modelId) {
        return resolveToolDeclaration(GET_INTERNAL_DOCS_DEFINITION, modelId);
    }
}
//# sourceMappingURL=get-internal-docs.js.map