import { isValidAgentMutation } from "../agents.js";
import { parsePropertyRef, resolvePropertyRef } from '../refs.js';
import { isBuiltinMutation, isBuiltinQuery } from "../schema-util.js";
export function findDuplicateIndices(array, key) {
    const indicesByValue = new Map();
    for (let i = 0; i < array.length; i++) {
        const value = array[i]?.[key];
        if (value !== undefined) {
            const indices = indicesByValue.get(value) ?? [];
            indices.push(i);
            indicesByValue.set(value, indices);
        }
    }
    const result = [];
    for (const [value, indices] of indicesByValue) {
        if (indices.length > 1) {
            result.push([value, indices]);
        }
    }
    return result;
}
export function pushErrors(errors, error) {
    if (error) {
        if (Array.isArray(error)) {
            if (error.length) {
                errors.push(...error);
            }
        }
        else {
            errors.push(error);
        }
    }
}
export function allowDisconnected(context, status) {
    return Boolean(context.allowDisconnectedLayers) && status !== 'notAvailable';
}
export function isValidShapeReference(context, layerState, shapeName) {
    if (layerState.status !== 'ok') {
        return allowDisconnected(context, layerState.status);
    }
    return Boolean(layerState.schema.shapes[shapeName]);
}
export async function isValidPropertyRef(context, inputRef) {
    const ref = typeof inputRef === 'string' ? parsePropertyRef(inputRef) : inputRef;
    if (!ref) {
        return false;
    }
    const { shapeName, propertyName } = ref;
    if ((shapeName === 'Query' && isBuiltinQuery(propertyName)) ||
        (shapeName === 'Mutation' &&
            (isBuiltinMutation(propertyName) || isValidAgentMutation(context.projectSchema, propertyName)))) {
        return true;
    }
    const resolvedLocally = Boolean(resolvePropertyRef(context.projectSchema, ref));
    if (resolvedLocally || ref.layerId === 'local') {
        return resolvedLocally;
    }
    const layerState = await context.resolveLayer(ref.layerId);
    return layerState.status === 'ok'
        ? Boolean(resolvePropertyRef(layerState.schema, ref))
        : allowDisconnected(context, layerState.status);
}
