/**
 * Pure mode × code-has-writes × autoApprove × surface → approval-or-block decision.
 *
 * Decision matrix:
 *
 *   mode      | code has writes | autoApprove | outcome
 *   ----------|-----------------|-------------|---------------------------------
 *   Ask/Plan  | no              | any         | allow ReadOnly,  no approval
 *   Ask/Plan  | yes             | any         | blocked (writes in read-only mode)
 *   Action    | no              | any         | allow ReadOnly,  no approval
 *   Action    | yes             | true        | allow ReadWrite, no approval (auto)
 *   Action    | yes             | false       | allow ReadWrite, approval required
 *
 * `btw=true` (internal "behave-the-way" override) forces Ask/Plan semantics
 * regardless of declared mode. Pure, no I/O, no side effects.
 */
import { AgentExecuteCodeMode } from '../../../contracts/agent-execute-code.js';
import { detectEmbeddedReadOnlyViolations } from './read-only-gate.js';
export const ExecuteCodeAccess = {
    ReadOnly: 'readOnly',
    ReadWrite: 'readWrite'
};
function isReadOnlyMode(mode, btw) {
    return (btw ||
        mode === AgentExecuteCodeMode.Ask ||
        mode === AgentExecuteCodeMode.Plan ||
        mode === AgentExecuteCodeMode.Shorty ||
        mode === AgentExecuteCodeMode.Review);
}
const APPROVAL_NOT_REQUIRED_READ = { required: false };
const APPROVAL_NOT_REQUIRED_AUTO = {
    required: false,
    reason: 'Auto-approve is enabled for this session.'
};
const APPROVAL_REQUIRED_WRITE = {
    required: true,
    reason: 'Spreadsheet write operations require user approval.'
};
export function classifyExecuteCode(input) {
    const writeViolations = detectEmbeddedReadOnlyViolations(input.code, input.surface);
    const codeHasWrites = writeViolations.length > 0;
    const readOnlyMode = isReadOnlyMode(input.mode, input.btw ?? false);
    if (readOnlyMode && codeHasWrites) {
        return { kind: 'blocked', disallowed: writeViolations };
    }
    if (!codeHasWrites) {
        return {
            kind: 'allow',
            access: ExecuteCodeAccess.ReadOnly,
            approval: APPROVAL_NOT_REQUIRED_READ
        };
    }
    return {
        kind: 'allow',
        access: ExecuteCodeAccess.ReadWrite,
        approval: input.autoApprove ? APPROVAL_NOT_REQUIRED_AUTO : APPROVAL_REQUIRED_WRITE
    };
}
/** Project params.access + autoApprove onto the approval requirement (no code analysis). */
export function evaluateAccessApproval(access, autoApprove) {
    if (access === ExecuteCodeAccess.ReadOnly) {
        return APPROVAL_NOT_REQUIRED_READ;
    }
    return autoApprove ? APPROVAL_NOT_REQUIRED_AUTO : APPROVAL_REQUIRED_WRITE;
}
//# sourceMappingURL=classify.js.map