"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.browseDocumentation = browseDocumentation;
exports.readDocumentation = readDocumentation;
const commandContext_1 = require("../commandContext");
const messages_1 = require("../messages");
const output_1 = require("../output");
const DOCUMENTATION_ROOT = 'documentation';
const DOCUMENTATION_INDEX_FILE = 'documentation.json';
function normalizeDocPath(value) {
    if (typeof value !== 'string') {
        return null;
    }
    const trimmed = value.trim();
    if (!trimmed) {
        return null;
    }
    const unified = trimmed.replace(/\\/g, '/').replace(/\/+/g, '/');
    const segments = unified.split('/');
    if (segments.some((segment) => !segment || segment === '.' || segment === '..')) {
        return null;
    }
    return segments.join('/');
}
function toDisplayDocPath(entry) {
    if (entry.endsWith('/README.md')) {
        return entry.slice(0, -'/README.md'.length);
    }
    if (entry.endsWith('/AGENTS.md')) {
        return `${entry.slice(0, -'/AGENTS.md'.length)}/agents`;
    }
    return entry;
}
function createDocAliasMap(entries) {
    const aliases = new Map();
    for (const entry of entries) {
        aliases.set(entry, entry);
        aliases.set(toDisplayDocPath(entry), entry);
    }
    return aliases;
}
function encodePathSegments(pathValue) {
    return pathValue
        .split('/')
        .map((segment) => encodeURIComponent(segment))
        .join('/');
}
function buildDocumentationIndexUrl(base) {
    return `${base.replace(/\/$/, '')}/${DOCUMENTATION_ROOT}/${encodeURIComponent(DOCUMENTATION_INDEX_FILE)}`;
}
function buildDocumentationFileUrl(base, relativePath) {
    return `${base.replace(/\/$/, '')}/${DOCUMENTATION_ROOT}/${encodePathSegments(relativePath)}`;
}
async function fetchDocumentationIndex(indexUrl, command) {
    let response;
    try {
        response = await fetch(indexUrl);
    }
    catch (error) {
        (0, messages_1.printErrorWithHelp)('Fetching documentation failed.', [error instanceof Error ? error.message : String(error)], { command });
        process.exitCode = 1;
        return null;
    }
    if (!response.ok) {
        (0, messages_1.printErrorWithHelp)(`Failed to fetch documentation from ${indexUrl}.`, [`HTTP ${response.status} ${response.statusText}`], { command });
        process.exitCode = 1;
        return null;
    }
    const payload = await response.json().catch(() => null);
    if (!Array.isArray(payload) || payload.some((entry) => typeof entry !== 'string')) {
        (0, messages_1.printErrorWithHelp)('Documentation index is invalid.', ['Retry in a moment or contact the platform team.'], { command });
        process.exitCode = 1;
        return null;
    }
    return payload;
}
async function browseDocumentation(options = {}) {
    await (0, commandContext_1.withPublicEnvironment)('documentation browse', async ({ envConfig }) => {
        if (!envConfig.cdnBase) {
            (0, messages_1.printErrorWithHelp)(`Environment "${envConfig.name}" does not include a documentation base URL.`, ['Set PLAYDROP_CDN_BASE or use an environment that publishes documentation assets.'], { command: 'documentation browse' });
            process.exitCode = 1;
            return;
        }
        const entries = await fetchDocumentationIndex(buildDocumentationIndexUrl(envConfig.cdnBase), 'documentation browse');
        if (!entries) {
            return;
        }
        const normalizedEntries = [...new Set(entries.map((entry) => normalizeDocPath(entry)).filter((entry) => Boolean(entry)))].sort((a, b) => a.localeCompare(b));
        const items = [...new Set(normalizedEntries.map((entry) => toDisplayDocPath(entry)))].sort((a, b) => a.localeCompare(b));
        if (options.json) {
            (0, output_1.printJson)({ items });
            return;
        }
        if (items.length === 0) {
            console.log('No documentation entries were returned.');
            return;
        }
        console.log('Documentation:\n');
        for (const item of items) {
            console.log(item);
        }
        console.log('\nNext: run "playdrop documentation read <path>" to open one entry.');
    });
}
async function readDocumentation(pathArg) {
    const normalizedTarget = normalizeDocPath(pathArg);
    if (!normalizedTarget) {
        (0, messages_1.printErrorWithHelp)('A documentation path is required.', ['Use a relative path such as runtime.', 'Run "playdrop documentation browse" to list available entries.'], { command: 'documentation read' });
        process.exitCode = 1;
        return;
    }
    await (0, commandContext_1.withPublicEnvironment)('documentation read', async ({ envConfig }) => {
        if (!envConfig.cdnBase) {
            (0, messages_1.printErrorWithHelp)(`Environment "${envConfig.name}" does not include a documentation base URL.`, ['Set PLAYDROP_CDN_BASE or use an environment that publishes documentation assets.'], { command: 'documentation read' });
            process.exitCode = 1;
            return;
        }
        const entries = await fetchDocumentationIndex(buildDocumentationIndexUrl(envConfig.cdnBase), 'documentation read');
        if (!entries) {
            return;
        }
        const normalizedEntries = [...new Set(entries.map((entry) => normalizeDocPath(entry)).filter((entry) => Boolean(entry)))];
        const aliases = createDocAliasMap(normalizedEntries);
        const resolvedTarget = aliases.get(normalizedTarget);
        if (!resolvedTarget) {
            (0, messages_1.printErrorWithHelp)(`Documentation entry "${normalizedTarget}" was not found.`, ['Run "playdrop documentation browse" to list available entries.'], { command: 'documentation read' });
            process.exitCode = 1;
            return;
        }
        const fileUrl = buildDocumentationFileUrl(envConfig.cdnBase, resolvedTarget);
        let response;
        try {
            response = await fetch(fileUrl);
        }
        catch (error) {
            (0, messages_1.printErrorWithHelp)(`Fetching documentation entry "${normalizedTarget}" failed.`, [error instanceof Error ? error.message : String(error)], { command: 'documentation read' });
            process.exitCode = 1;
            return;
        }
        if (!response.ok) {
            (0, messages_1.printErrorWithHelp)(`Failed to fetch "${normalizedTarget}".`, [`HTTP ${response.status} ${response.statusText}`], { command: 'documentation read' });
            process.exitCode = 1;
            return;
        }
        process.stdout.write(await response.text());
    });
}
