/** Path exclusion utilities — ports isAllowPath/excludeFiles/excludeOperations from aurora-cli HBS. */
import path from 'node:path';
import { toKebabCase } from './string-utils.js';
// prettier-ignore
const OPERATIONS_PATTERN_PATHS = {
    count: [
        ['src', '@app', '__bounded_context_name__', '__module_name__', 'application', 'count'],
        ['src', '@app', '__bounded_context_name__', '__module_name__', 'application', 'count', '__bounded_context_name__-count-__module_name__.handler.spec.ts'],
        ['src', '@app', '__bounded_context_name__', '__module_name__', 'application', 'count', '__bounded_context_name__-count-__module_name__.handler.ts'],
        ['src', '@app', '__bounded_context_name__', '__module_name__', 'application', 'count', '__bounded_context_name__-count-__module_name__.service.spec.ts'],
        ['src', '@app', '__bounded_context_name__', '__module_name__', 'application', 'count', '__bounded_context_name__-count-__module_name__.service.ts'],
    ],
    create: [
        ['src', '@api', '__bounded_context_name__', '__module_name__', 'controllers', '__bounded_context_name__-create-__module_name__.controller.spec.ts'],
        ['src', '@api', '__bounded_context_name__', '__module_name__', 'controllers', '__bounded_context_name__-create-__module_name__.controller.ts'],
        ['src', '@api', '__bounded_context_name__', '__module_name__', 'resolvers', '__bounded_context_name__-create-__module_name__.resolver.spec.ts'],
        ['src', '@api', '__bounded_context_name__', '__module_name__', 'resolvers', '__bounded_context_name__-create-__module_name__.resolver.ts'],
        ['src', '@app', '__bounded_context_name__', '__module_name__', 'application', 'create', '__bounded_context_name__-create-__module_name__.handler.spec.ts'],
        ['src', '@app', '__bounded_context_name__', '__module_name__', 'application', 'create', '__bounded_context_name__-create-__module_name__.handler.ts'],
        ['src', '@app', '__bounded_context_name__', '__module_name__', 'application', 'create', '__bounded_context_name__-create-__module_name__.service.spec.ts'],
        ['src', '@app', '__bounded_context_name__', '__module_name__', 'application', 'create', '__bounded_context_name__-create-__module_name__.service.ts'],
    ],
    createBatch: [
        ['src', '@api', '__bounded_context_name__', '__module_name__', 'controllers', '__bounded_context_name__-create-__module_names__.controller.spec.ts'],
        ['src', '@api', '__bounded_context_name__', '__module_name__', 'controllers', '__bounded_context_name__-create-__module_names__.controller.ts'],
        ['src', '@api', '__bounded_context_name__', '__module_name__', 'resolvers', '__bounded_context_name__-create-__module_names__.resolver.spec.ts'],
        ['src', '@api', '__bounded_context_name__', '__module_name__', 'resolvers', '__bounded_context_name__-create-__module_names__.resolver.ts'],
        ['src', '@app', '__bounded_context_name__', '__module_name__', 'application', 'create', '__bounded_context_name__-create-__module_names__.handler.spec.ts'],
        ['src', '@app', '__bounded_context_name__', '__module_name__', 'application', 'create', '__bounded_context_name__-create-__module_names__.handler.ts'],
        ['src', '@app', '__bounded_context_name__', '__module_name__', 'application', 'create', '__bounded_context_name__-create-__module_names__.service.spec.ts'],
        ['src', '@app', '__bounded_context_name__', '__module_name__', 'application', 'create', '__bounded_context_name__-create-__module_names__.service.ts'],
    ],
    delete: [
        ['src', '@api', '__bounded_context_name__', '__module_name__', 'controllers', '__bounded_context_name__-delete-__module_names__.controller.spec.ts'],
        ['src', '@api', '__bounded_context_name__', '__module_name__', 'controllers', '__bounded_context_name__-delete-__module_names__.controller.ts'],
        ['src', '@api', '__bounded_context_name__', '__module_name__', 'resolvers', '__bounded_context_name__-delete-__module_names__.resolver.spec.ts'],
        ['src', '@api', '__bounded_context_name__', '__module_name__', 'resolvers', '__bounded_context_name__-delete-__module_names__.resolver.ts'],
        ['src', '@app', '__bounded_context_name__', '__module_name__', 'application', 'delete', '__bounded_context_name__-delete-__module_names__.handler.spec.ts'],
        ['src', '@app', '__bounded_context_name__', '__module_name__', 'application', 'delete', '__bounded_context_name__-delete-__module_names__.handler.ts'],
        ['src', '@app', '__bounded_context_name__', '__module_name__', 'application', 'delete', '__bounded_context_name__-delete-__module_names__.service.spec.ts'],
        ['src', '@app', '__bounded_context_name__', '__module_name__', 'application', 'delete', '__bounded_context_name__-delete-__module_names__.service.ts'],
    ],
    getRaw: [
        ['src', '@api', '__bounded_context_name__', '__module_name__', 'controllers', '__bounded_context_name__-get-raw-__module_names__.controller.spec.ts'],
        ['src', '@api', '__bounded_context_name__', '__module_name__', 'controllers', '__bounded_context_name__-get-raw-__module_names__.controller.ts'],
        ['src', '@api', '__bounded_context_name__', '__module_name__', 'resolvers', '__bounded_context_name__-get-raw-__module_names__.resolver.spec.ts'],
        ['src', '@api', '__bounded_context_name__', '__module_name__', 'resolvers', '__bounded_context_name__-get-raw-__module_names__.resolver.ts'],
        ['src', '@app', '__bounded_context_name__', '__module_name__', 'application', 'get', '__bounded_context_name__-get-raw-__module_names__.handler.spec.ts'],
        ['src', '@app', '__bounded_context_name__', '__module_name__', 'application', 'get', '__bounded_context_name__-get-raw-__module_names__.handler.ts'],
        ['src', '@app', '__bounded_context_name__', '__module_name__', 'application', 'get', '__bounded_context_name__-get-raw-__module_names__.service.spec.ts'],
        ['src', '@app', '__bounded_context_name__', '__module_name__', 'application', 'get', '__bounded_context_name__-get-raw-__module_names__.service.ts'],
    ],
    max: [
        ['src', '@app', '__bounded_context_name__', '__module_name__', 'application', 'max'],
        ['src', '@app', '__bounded_context_name__', '__module_name__', 'application', 'max', '__bounded_context_name__-max-__module_name__.handler.spec.ts'],
        ['src', '@app', '__bounded_context_name__', '__module_name__', 'application', 'max', '__bounded_context_name__-max-__module_name__.handler.ts'],
        ['src', '@app', '__bounded_context_name__', '__module_name__', 'application', 'max', '__bounded_context_name__-max-__module_name__.service.spec.ts'],
        ['src', '@app', '__bounded_context_name__', '__module_name__', 'application', 'max', '__bounded_context_name__-max-__module_name__.service.ts'],
    ],
    min: [
        ['src', '@app', '__bounded_context_name__', '__module_name__', 'application', 'min'],
        ['src', '@app', '__bounded_context_name__', '__module_name__', 'application', 'min', '__bounded_context_name__-min-__module_name__.handler.spec.ts'],
        ['src', '@app', '__bounded_context_name__', '__module_name__', 'application', 'min', '__bounded_context_name__-min-__module_name__.handler.ts'],
        ['src', '@app', '__bounded_context_name__', '__module_name__', 'application', 'min', '__bounded_context_name__-min-__module_name__.service.spec.ts'],
        ['src', '@app', '__bounded_context_name__', '__module_name__', 'application', 'min', '__bounded_context_name__-min-__module_name__.service.ts'],
    ],
    sum: [
        ['src', '@app', '__bounded_context_name__', '__module_name__', 'application', 'sum'],
        ['src', '@app', '__bounded_context_name__', '__module_name__', 'application', 'sum', '__bounded_context_name__-sum-__module_name__.handler.spec.ts'],
        ['src', '@app', '__bounded_context_name__', '__module_name__', 'application', 'sum', '__bounded_context_name__-sum-__module_name__.handler.ts'],
        ['src', '@app', '__bounded_context_name__', '__module_name__', 'application', 'sum', '__bounded_context_name__-sum-__module_name__.service.spec.ts'],
        ['src', '@app', '__bounded_context_name__', '__module_name__', 'application', 'sum', '__bounded_context_name__-sum-__module_name__.service.ts'],
    ],
    update: [
        ['src', '@api', '__bounded_context_name__', '__module_name__', 'controllers', '__bounded_context_name__-update-__module_names__.controller.spec.ts'],
        ['src', '@api', '__bounded_context_name__', '__module_name__', 'controllers', '__bounded_context_name__-update-__module_names__.controller.ts'],
        ['src', '@api', '__bounded_context_name__', '__module_name__', 'resolvers', '__bounded_context_name__-update-__module_names__.resolver.spec.ts'],
        ['src', '@api', '__bounded_context_name__', '__module_name__', 'resolvers', '__bounded_context_name__-update-__module_names__.resolver.ts'],
        ['src', '@app', '__bounded_context_name__', '__module_name__', 'application', 'update', '__bounded_context_name__-update-__module_names__.handler.spec.ts'],
        ['src', '@app', '__bounded_context_name__', '__module_name__', 'application', 'update', '__bounded_context_name__-update-__module_names__.handler.ts'],
        ['src', '@app', '__bounded_context_name__', '__module_name__', 'application', 'update', '__bounded_context_name__-update-__module_names__.service.spec.ts'],
        ['src', '@app', '__bounded_context_name__', '__module_name__', 'application', 'update', '__bounded_context_name__-update-__module_names__.service.ts'],
    ],
    updateAndIncrement: [
        ['src', '@app', '__bounded_context_name__', '__module_name__', 'application', 'update', '__bounded_context_name__-update-and-increment-__module_names__.handler.spec.ts'],
        ['src', '@app', '__bounded_context_name__', '__module_name__', 'application', 'update', '__bounded_context_name__-update-and-increment-__module_names__.handler.ts'],
        ['src', '@app', '__bounded_context_name__', '__module_name__', 'application', 'update', '__bounded_context_name__-update-and-increment-__module_names__.service.spec.ts'],
        ['src', '@app', '__bounded_context_name__', '__module_name__', 'application', 'update', '__bounded_context_name__-update-and-increment-__module_names__.service.ts'],
    ],
    upsert: [
        ['src', '@api', '__bounded_context_name__', '__module_name__', 'controllers', '__bounded_context_name__-upsert-__module_name__.controller.spec.ts'],
        ['src', '@api', '__bounded_context_name__', '__module_name__', 'controllers', '__bounded_context_name__-upsert-__module_name__.controller.ts'],
        ['src', '@api', '__bounded_context_name__', '__module_name__', 'resolvers', '__bounded_context_name__-upsert-__module_name__.resolver.spec.ts'],
        ['src', '@api', '__bounded_context_name__', '__module_name__', 'resolvers', '__bounded_context_name__-upsert-__module_name__.resolver.ts'],
        ['src', '@app', '__bounded_context_name__', '__module_name__', 'application', 'upsert'],
        ['src', '@app', '__bounded_context_name__', '__module_name__', 'application', 'upsert', '__bounded_context_name__-upsert-__module_name__.handler.spec.ts'],
        ['src', '@app', '__bounded_context_name__', '__module_name__', 'application', 'upsert', '__bounded_context_name__-upsert-__module_name__.handler.ts'],
        ['src', '@app', '__bounded_context_name__', '__module_name__', 'application', 'upsert', '__bounded_context_name__-upsert-__module_name__.service.spec.ts'],
        ['src', '@app', '__bounded_context_name__', '__module_name__', 'application', 'upsert', '__bounded_context_name__-upsert-__module_name__.service.ts'],
    ],
};
function resolvePatternPaths(patterns, boundedContextName, moduleName, moduleNames) {
    const resolved = new Set();
    for (const parts of patterns) {
        resolved.add(path.join(...parts.map((part) => part
            .replaceAll('__bounded_context_name__', toKebabCase(boundedContextName))
            .replaceAll('__module_name__', toKebabCase(moduleName))
            .replaceAll('__module_names__', toKebabCase(moduleNames)))));
    }
    return resolved;
}
/**
 * Check if a path is allowed against `excludedFiles` and `excludedOperations`.
 * Low-level implementation used by the property-filters wrapper.
 */
export function isPathAllowedByExclusions(excludedFiles, excludedOperations, boundedContextName, moduleName, moduleNames, operation, ...pathSegments) {
    const filePath = path.join(...pathSegments);
    if (Array.isArray(excludedFiles) &&
        excludedFiles.length > 0 &&
        excludedFiles.includes(filePath))
        return false;
    if (Array.isArray(excludedOperations) && excludedOperations.length > 0) {
        const patterns = OPERATIONS_PATTERN_PATHS[operation];
        if (patterns) {
            const resolved = resolvePatternPaths(patterns, boundedContextName, moduleName, moduleNames);
            if (excludedOperations.includes(operation) && resolved.has(filePath)) {
                return false;
            }
        }
    }
    return true;
}
/** Filter target paths against excluded files/operations. Used by file-manager.ts. */
export function isFilePathAllowed(targetPath, excludedFiles, excludedOperations, boundedContextName, moduleName, moduleNames) {
    // Normalize to POSIX separators for consistent comparison
    const normalizedPath = targetPath.split(path.sep).join('/');
    if (excludedFiles.length > 0) {
        for (const excluded of excludedFiles) {
            if (normalizedPath === excluded || normalizedPath.endsWith(excluded)) {
                return false;
            }
            // Glob-style suffix: `src/@app/**`
            if (excluded.endsWith('/**')) {
                const prefix = excluded.slice(0, -3);
                if (normalizedPath.startsWith(prefix)) {
                    return false;
                }
            }
        }
    }
    if (excludedOperations.length > 0) {
        for (const operation of excludedOperations) {
            const patterns = OPERATIONS_PATTERN_PATHS[operation];
            if (!patterns)
                continue;
            const resolved = resolvePatternPaths(patterns, boundedContextName, moduleName, moduleNames);
            for (const resolvedPath of resolved) {
                const normalizedResolved = resolvedPath.split(path.sep).join('/');
                if (normalizedPath === normalizedResolved ||
                    normalizedPath.endsWith(normalizedResolved)) {
                    return false;
                }
            }
        }
    }
    return true;
}
