export function isShellGenerationRecord(value) {
    return typeof value === "object" && value !== null && !Array.isArray(value);
}
export function shellGenerationInputEnvelope(request) {
    if (!isShellGenerationRecord(request)) {
        return { input: {} };
    }
    const { context, executor: _executor, provider: _provider, preferredProvider: _preferredProvider, ...input } = request;
    return {
        input,
        context: isShellGenerationRecord(context) ? context : undefined,
    };
}
export function requireShellGenerationExecutorOutput(result) {
    if (!result.ok) {
        throw new Error(result.error.message);
    }
    if (typeof result.output !== "object" || result.output === null || Array.isArray(result.output)) {
        throw new Error("Shell generation executor returned an invalid output envelope");
    }
    return result.output;
}
export function withShellGenerationProviderFlags(output) {
    return {
        ...output,
        dryRun: false,
        providerCalled: true,
        executionBlocked: true,
        unsafeSideEffects: false,
    };
}
function invalidOutput(field) {
    return new Error(`Shell generation executor returned an invalid ${field}`);
}
export function requireStringField(output, field, options = {}) {
    const value = output[field];
    if (typeof value !== "string" || (options.nonEmpty === true && value.trim().length === 0)) {
        throw invalidOutput(field);
    }
    return value;
}
export function optionalStringField(output, field) {
    const value = output[field];
    if (value === undefined) {
        return undefined;
    }
    if (typeof value !== "string") {
        throw invalidOutput(field);
    }
    return value;
}
export function requireNumberField(output, field) {
    const value = output[field];
    if (typeof value !== "number" || !Number.isFinite(value)) {
        throw invalidOutput(field);
    }
    return value;
}
export function requireBooleanField(output, field) {
    const value = output[field];
    if (typeof value !== "boolean") {
        throw invalidOutput(field);
    }
    return value;
}
export function requireStringArrayField(output, field) {
    const value = output[field];
    if (!Array.isArray(value) || value.some((entry) => typeof entry !== "string")) {
        throw invalidOutput(field);
    }
    return value;
}
export function optionalStringArrayField(output, field) {
    const value = output[field];
    if (value === undefined) {
        return undefined;
    }
    return requireStringArrayField(output, field);
}
export function requireRecordField(output, field) {
    const value = output[field];
    if (!isShellGenerationRecord(value)) {
        throw invalidOutput(field);
    }
    return value;
}
export function optionalRecordField(output, field) {
    const value = output[field];
    if (value === undefined) {
        return undefined;
    }
    if (!isShellGenerationRecord(value)) {
        throw invalidOutput(field);
    }
    return value;
}
export function requireLiteralField(output, field, values) {
    const value = output[field];
    if (typeof value !== "string" || !isStringLiteral(value, values)) {
        throw invalidOutput(field);
    }
    return value;
}
export function requireRecordArrayField(output, field) {
    const value = output[field];
    if (!Array.isArray(value) || value.some((entry) => !isShellGenerationRecord(entry))) {
        throw invalidOutput(field);
    }
    return value;
}
function isStringLiteral(value, values) {
    return values.some((candidate) => candidate === value);
}
export function requireStringLiteralArrayField(output, field, values) {
    const entries = requireStringArrayField(output, field);
    const normalized = [];
    for (const entry of entries) {
        if (!isStringLiteral(entry, values)) {
            throw invalidOutput(field);
        }
        normalized.push(entry);
    }
    return normalized;
}
export function requireProviderResultEnvelope(result, toolId) {
    if (!isShellGenerationRecord(result) ||
        result.toolId !== toolId ||
        typeof result.ok !== "boolean") {
        throw invalidOutput("provider result envelope");
    }
    return result;
}
export function requireProviderAudit(result) {
    const audit = result.audit;
    if (!Array.isArray(audit) || audit.some((entry) => !isShellGenerationRecord(entry))) {
        throw invalidOutput("provider result audit");
    }
    return audit;
}
export function requireProviderEvents(result) {
    return requireStringArrayField(result, "events");
}
export function requireProviderFailureError(result, allowedCodes, allowedBoundaries) {
    const error = requireRecordField(result, "error");
    const code = requireLiteralField(error, "code", allowedCodes);
    const message = requireStringField(error, "message", { nonEmpty: true });
    const boundary = requireLiteralField(error, "boundary", allowedBoundaries);
    if (error.publicSafe !== true || error.internalDetailExposed !== false) {
        throw invalidOutput("provider result error safety flags");
    }
    return {
        code,
        message,
        boundary,
        publicSafe: true,
        internalDetailExposed: false,
    };
}
