/*
 * Copyright (c) 2025, Salesforce, Inc.
 * SPDX-License-Identifier: Apache-2
 * For full license text, see the license.txt file in the repo root or http://www.apache.org/licenses/LICENSE-2.0
 */
/** HTTP methods that can appear in OpenAPI paths */
const HTTP_METHODS = ['get', 'put', 'post', 'delete', 'options', 'head', 'patch', 'trace'];
/**
 * Collapses an OpenAPI schema for context-efficient representation.
 *
 * This function implements a three-tier disclosure model:
 *
 * 1. **No options provided (default):**
 *    - Paths: `{"/products": ["get", "post"]}` (method names only)
 *    - Schemas: `{"Product": {}}` (keys only)
 *    - Examples: `{"ProductExample": {}}` (keys only)
 *
 * 2. **Selective expansion:**
 *    - Only specified paths/schemas/examples are fully expanded
 *    - Everything else remains collapsed
 *
 * Non-collapsible sections (info, servers, security, tags, etc.) are preserved as-is.
 *
 * @param schema - The OpenAPI schema to collapse
 * @param options - Options controlling what to expand
 * @returns The collapsed schema
 *
 * @example
 * // Collapse everything (default behavior)
 * const collapsed = collapseOpenApiSchema(fullSchema);
 *
 * @example
 * // Expand only /products path and Product schema
 * const collapsed = collapseOpenApiSchema(fullSchema, {
 *   expandPaths: ['/products'],
 *   expandSchemas: ['Product']
 * });
 */
export function collapseOpenApiSchema(schema, options = {}) {
    const { expandPaths = [], expandSchemas = [], expandExamples = [] } = options;
    // Start with a shallow copy
    const result = { ...schema };
    // Collapse paths
    if (schema.paths) {
        result.paths = collapsePaths(schema.paths, expandPaths);
    }
    // Collapse components
    if (schema.components) {
        result.components = {
            ...schema.components,
        };
        if (schema.components.schemas) {
            result.components.schemas = collapseSchemas(schema.components.schemas, expandSchemas);
        }
        if (schema.components.examples) {
            result.components.examples = collapseExamples(schema.components.examples, expandExamples);
        }
    }
    return result;
}
/**
 * Collapses path items to show only HTTP method names.
 *
 * @param paths - The paths object from an OpenAPI schema
 * @param expandPaths - Paths to keep fully expanded
 * @returns Collapsed paths object
 */
function collapsePaths(paths, expandPaths) {
    const result = {};
    const expandSet = new Set(expandPaths);
    for (const [pathKey, pathItem] of Object.entries(paths)) {
        if (expandSet.has(pathKey)) {
            // Keep full path item for expanded paths
            result[pathKey] = pathItem;
        }
        else {
            // Collapse to method names only
            const methods = Object.keys(pathItem).filter((key) => HTTP_METHODS.includes(key));
            result[pathKey] = methods;
        }
    }
    return result;
}
/**
 * Collapses schemas to show only keys with empty objects.
 *
 * @param schemas - The schemas object from components
 * @param expandSchemas - Schema names to keep fully expanded
 * @returns Collapsed schemas object
 */
function collapseSchemas(schemas, expandSchemas) {
    const result = {};
    const expandSet = new Set(expandSchemas);
    for (const [schemaName, schemaValue] of Object.entries(schemas)) {
        if (expandSet.has(schemaName)) {
            // Keep full schema for expanded schemas
            result[schemaName] = schemaValue;
        }
        else {
            // Collapse to empty object
            result[schemaName] = {};
        }
    }
    return result;
}
/**
 * Collapses examples to show only keys with empty objects.
 *
 * @param examples - The examples object from components
 * @param expandExamples - Example names to keep fully expanded
 * @returns Collapsed examples object
 */
function collapseExamples(examples, expandExamples) {
    const result = {};
    const expandSet = new Set(expandExamples);
    for (const [exampleName, exampleValue] of Object.entries(examples)) {
        if (expandSet.has(exampleName)) {
            // Keep full example for expanded examples
            result[exampleName] = exampleValue;
        }
        else {
            // Collapse to empty object
            result[exampleName] = {};
        }
    }
    return result;
}
/**
 * Checks if a schema has been collapsed (i.e., is in outline form).
 *
 * @param schema - The schema to check
 * @returns true if paths are collapsed (arrays) or schemas are empty objects
 */
export function isCollapsedSchema(schema) {
    // Check if any path is collapsed (array of methods instead of full path item)
    if (schema.paths) {
        for (const pathItem of Object.values(schema.paths)) {
            if (Array.isArray(pathItem)) {
                return true;
            }
        }
    }
    // Check if any schema is collapsed (empty object)
    if (schema.components?.schemas) {
        for (const schemaValue of Object.values(schema.components.schemas)) {
            if (typeof schemaValue === 'object' && schemaValue !== null && Object.keys(schemaValue).length === 0) {
                return true;
            }
        }
    }
    return false;
}
/**
 * Gets the list of available path keys from a schema.
 *
 * @param schema - The OpenAPI schema
 * @returns Array of path keys (e.g., ["/products", "/orders"])
 */
export function getPathKeys(schema) {
    return schema.paths ? Object.keys(schema.paths) : [];
}
/**
 * Gets the list of available schema names from a schema.
 *
 * @param schema - The OpenAPI schema
 * @returns Array of schema names (e.g., ["Product", "Order"])
 */
export function getSchemaNames(schema) {
    return schema.components?.schemas ? Object.keys(schema.components.schemas) : [];
}
/**
 * Gets the list of available example names from a schema.
 *
 * @param schema - The OpenAPI schema
 * @returns Array of example names
 */
export function getExampleNames(schema) {
    return schema.components?.examples ? Object.keys(schema.components.examples) : [];
}
//# sourceMappingURL=collapse.js.map