function matchesTypePattern(nodeType, pattern) {
    if ('*' === pattern) return true;
    const regexPattern = pattern.replace(/\\/g, '\\\\').replace(/\./g, '\\.').replace(/\*/g, '.*');
    const regex = new RegExp(`^${regexPattern}$`);
    return regex.test(nodeType);
}
function matchesHandleTarget(target, nodeType, handleId) {
    const nodeTypeMatches = matchesTypePattern(nodeType, target.nodeType);
    if (!nodeTypeMatches) return false;
    if (void 0 !== target.handleId && target.handleId !== handleId) return false;
    return true;
}
function checkHandleTargetConstraint(nodeType, handleId, allowed, forbidden) {
    if (forbidden) {
        const isForbidden = forbidden.some((target)=>matchesHandleTarget(target, nodeType, handleId));
        if (isForbidden) return false;
    }
    if (allowed) {
        const isAllowed = allowed.some((target)=>matchesHandleTarget(target, nodeType, handleId));
        return isAllowed;
    }
    return true;
}
function checkCategoryConstraint(category, allowed, forbidden) {
    if (!category) return !allowed && !forbidden;
    if (forbidden?.includes(category)) return false;
    if (allowed && !allowed.includes(category)) return false;
    return true;
}
function validateConnection(context) {
    const { sourceNode, sourceHandle, targetNode, targetHandle } = context;
    const sourceConstraints = sourceHandle.constraints;
    const targetConstraints = targetHandle.constraints;
    if (sourceHandle.handleType === targetHandle.handleType && 'artifact' !== sourceHandle.handleType) return {
        valid: false,
        reason: `Cannot connect ${sourceHandle.handleType} to ${targetHandle.handleType}. Outputs must connect to inputs.`
    };
    if (sourceConstraints) {
        const allowedTarget = checkHandleTargetConstraint(targetNode.type, targetHandle.id, sourceConstraints.allowedTargets, sourceConstraints.forbiddenTargets);
        if (!allowedTarget) {
            const message = `${sourceNode.type} cannot connect to ${targetNode.type}`;
            return {
                valid: false,
                reason: message
            };
        }
        const allowedCategory = checkCategoryConstraint(targetNode.category, sourceConstraints.allowedTargetCategories, sourceConstraints.forbiddenTargetCategories);
        if (!allowedCategory) return {
            valid: false,
            reason: `Cannot connect to nodes in category: ${targetNode.category}`
        };
        sourceConstraints.customValidation;
    }
    if (targetConstraints) {
        const allowedSource = checkHandleTargetConstraint(sourceNode.type, sourceHandle.id, targetConstraints.allowedSources, targetConstraints.forbiddenSources);
        if (!allowedSource) {
            const message = `${targetNode.type} cannot accept connections from ${sourceNode.type}`;
            return {
                valid: false,
                reason: message
            };
        }
        const allowedCategory = checkCategoryConstraint(sourceNode.category, targetConstraints.allowedSourceCategories, targetConstraints.forbiddenSourceCategories);
        if (!allowedCategory) return {
            valid: false,
            reason: `Cannot accept connections from nodes in category: ${sourceNode.category}`
        };
        targetConstraints.customValidation;
    }
    return {
        valid: true
    };
}
function canAcceptMoreConnections(handle, currentConnectionCount) {
    if (!handle.constraints?.maxConnections) return true;
    return currentConnectionCount < handle.constraints.maxConnections;
}
function meetsMinimumConnections(handle, currentConnectionCount) {
    const minRequired = handle.constraints?.minConnections ?? 0;
    return currentConnectionCount >= minRequired;
}
export { canAcceptMoreConnections, checkCategoryConstraint, meetsMinimumConnections, validateConnection };
