import { parseAffectedPaths, parseDecisionCapabilities, readToolRisk, } from "../permissions/PermissionDecisionRegistry.js";
import { redactPublicDiagnosticText } from "../security/redactionBoundary.js";
import { isRecord } from "../utils/json.js";
import { readOptionalString, readString, readStringArray, } from "./requestParsing.js";
export function readPermissionRequestStatusParam(value) {
    if (value === null || value === "")
        return undefined;
    if (value === "pending" ||
        value === "replying" ||
        value === "answered" ||
        value === "reply_failed") {
        return value;
    }
    return "pending";
}
export function readPermissionDecisionStatusParam(value) {
    if (value === null || value === "")
        return undefined;
    if (value === "active" || value === "revoked")
        return value;
    return "active";
}
export function readPermissionOption(value) {
    if (value === "approve_once" ||
        value === "allow_for_session" ||
        value === "allow_for_project" ||
        value === "always_allow" ||
        value === "always_allow_tool_class" ||
        value === "full_escape_hatch_run" ||
        value === "full_escape_hatch_project" ||
        value === "full_escape_hatch_global" ||
        value === "deny" ||
        value === "deny_and_remember") {
        return value;
    }
    return undefined;
}
export function readPermissionCapabilities(value) {
    if (!Array.isArray(value))
        return undefined;
    const capabilities = value.filter((item) => item === "local_tools" || item === "external_service_mutations");
    return capabilities.length > 0 ? capabilities : undefined;
}
export function formatPermissionRequestRecord(record) {
    const selectedOption = readPermissionOption(record.selectedOption);
    return {
        id: record.id,
        status: record.status,
        request: formatPermissionRequestPayload(record.requestJson),
        evaluation: formatPermissionEvaluationPayload(JSON.parse(record.evaluationJson)),
        ...(selectedOption ? { selectedOption } : {}),
        ...(record.opencodeReply ? { opencodeReply: record.opencodeReply } : {}),
        ...(record.lastError
            ? { lastError: sanitizePermissionFreeformText(record.lastError) }
            : {}),
        ...(record.answeredAt ? { answeredAt: record.answeredAt } : {}),
        createdAt: record.createdAt,
        updatedAt: record.updatedAt,
    };
}
export function formatPermissionActivityRecord(record) {
    const selectedOption = readPermissionOption(record.selectedOption);
    return {
        id: record.id,
        kind: record.kind,
        at: record.at,
        ...(record.status ? { status: record.status } : {}),
        ...(selectedOption ? { selectedOption } : {}),
        ...(record.opencodeReply === "once" || record.opencodeReply === "reject"
            ? { opencodeReply: record.opencodeReply }
            : {}),
        toolCall: formatPermissionToolCallFields({
            name: record.toolName,
            title: record.toolTitle,
            risk: record.toolRisk,
            inputPreview: record.inputPreview,
            affectedPaths: parseAffectedPaths(record.affectedPathsJson),
        }),
        ...(record.externalServiceMutation
            ? { externalServiceMutation: true }
            : {}),
        ...(record.denyOnlyDiagnostics
            ? {
                denyOnlyDiagnostics: formatPermissionDenyOnlyDiagnostics(record.denyOnlyDiagnostics),
            }
            : {}),
        ...(record.error
            ? { error: sanitizePermissionFreeformText(record.error) }
            : {}),
        ...(record.revokeReason
            ? { revokeReason: sanitizePermissionFreeformText(record.revokeReason) }
            : {}),
        ...(record.revokeSource ? { revokeSource: record.revokeSource } : {}),
    };
}
export function formatPermissionDecisionRecord(record) {
    return {
        id: record.id,
        scope: record.scope,
        effect: record.effect,
        option: record.option,
        capabilities: parseDecisionCapabilities(record.capabilitiesJson),
        status: record.status,
        toolCall: formatPermissionToolCallFields({
            name: record.toolName,
            title: record.toolTitle,
            risk: record.toolRisk,
            inputPreview: record.inputPreview,
            affectedPaths: parseAffectedPaths(record.affectedPathsJson),
        }),
        createdAt: record.createdAt,
        updatedAt: record.updatedAt,
        ...(record.revokedAt ? { revokedAt: record.revokedAt } : {}),
        ...(record.revokeReason
            ? { revokeReason: sanitizePermissionFreeformText(record.revokeReason) }
            : {}),
        ...(record.revokeSource ? { revokeSource: record.revokeSource } : {}),
    };
}
export function formatPermissionEvaluationPayload(value) {
    if (!isRecord(value))
        return formatUnknownPermissionEvaluationPayload();
    if (value.verdict === "requires_approval") {
        return {
            verdict: "requires_approval",
            request: formatPermissionRequestObject(value.request),
        };
    }
    if (value.verdict === "allowed") {
        return {
            verdict: "allowed",
            ...(value.source === "existing_scope" ? { source: value.source } : {}),
            ...(value.decision
                ? { decision: formatPermissionEvaluationDecision(value.decision) }
                : {}),
        };
    }
    if (value.verdict === "blocked") {
        return {
            verdict: "blocked",
            ...(typeof value.reason === "string"
                ? { reason: sanitizePermissionFreeformText(value.reason) }
                : {}),
            ...(typeof value.externalServiceMutation === "boolean"
                ? { externalServiceMutation: value.externalServiceMutation }
                : {}),
            ...(value.denyOnlyDiagnostics
                ? {
                    denyOnlyDiagnostics: formatPermissionDenyOnlyDiagnostics(value.denyOnlyDiagnostics),
                }
                : {}),
        };
    }
    return formatUnknownPermissionEvaluationPayload();
}
export function readRisk(value) {
    if (value === "read" ||
        value === "write" ||
        value === "shell" ||
        value === "network" ||
        value === "external") {
        return value;
    }
    return "read";
}
function formatPermissionRequestPayload(requestJson) {
    return formatPermissionRequestObject(JSON.parse(requestJson));
}
function formatUnknownPermissionEvaluationPayload() {
    return { verdict: "unknown" };
}
function formatPermissionRequestObject(value) {
    if (!isRecord(value)) {
        return {
            toolCall: formatPermissionToolCallPayload(undefined),
        };
    }
    const output = {};
    output.toolCall = formatPermissionToolCallPayload(value.toolCall);
    const reason = readOptionalString(value.reason);
    if (reason)
        output.reason = sanitizePermissionFreeformText(reason);
    const options = readPermissionOptions(value.options);
    if (options)
        output.options = options;
    if (isPermissionPolicyRecommendation(value.policyRecommendation)) {
        output.policyRecommendation = value.policyRecommendation;
    }
    const suggestedScope = readPermissionScopeName(value.suggestedScope);
    if (suggestedScope)
        output.suggestedScope = suggestedScope;
    const capabilities = readPermissionCapabilities(value.capabilities);
    if (capabilities)
        output.capabilities = capabilities;
    if (typeof value.externalServiceMutation === "boolean") {
        output.externalServiceMutation = value.externalServiceMutation;
    }
    if (value.externalServiceCapabilityDefault === "unchecked") {
        output.externalServiceCapabilityDefault = "unchecked";
    }
    if (value.denyOnlyDiagnostics) {
        output.denyOnlyDiagnostics = formatPermissionDenyOnlyDiagnostics(value.denyOnlyDiagnostics);
    }
    const hardDenyReason = readOptionalString(value.hardDenyReason);
    if (hardDenyReason) {
        output.hardDenyReason = sanitizePermissionFreeformText(hardDenyReason);
    }
    return output;
}
function formatPermissionToolCallPayload(value) {
    if (!isRecord(value)) {
        return formatPermissionToolCallFields({
            name: "unknown",
            title: "Unknown tool",
            risk: "read",
            inputPreview: "",
            affectedPaths: [],
        });
    }
    return formatPermissionToolCallFields({
        name: readString(value.name, "unknown"),
        title: readString(value.title, "Unknown tool"),
        risk: readRisk(value.risk),
        inputPreview: readString(value.inputPreview, ""),
        affectedPaths: readStringArray(value.affectedPaths) ?? [],
    });
}
function formatPermissionToolCallFields(input) {
    return {
        name: sanitizePermissionFreeformText(input.name),
        title: sanitizePermissionFreeformText(input.title),
        risk: typeof input.risk === "string" ? readToolRisk(input.risk) : "read",
        inputPreview: sanitizePermissionFreeformText(input.inputPreview),
        affectedPaths: input.affectedPaths.map(sanitizePermissionFreeformText),
    };
}
function formatPermissionEvaluationDecision(value) {
    if (!isRecord(value))
        return {};
    const output = {};
    const option = readPermissionOption(value.option);
    if (option)
        output.option = option;
    if (value.effect === "allow" || value.effect === "deny")
        output.effect = value.effect;
    const scope = readPermissionScopeName(value.scope);
    if (scope)
        output.scope = scope;
    const capabilities = readPermissionCapabilities(value.capabilities);
    if (capabilities)
        output.capabilities = capabilities;
    if (typeof value.expiresAt === "string")
        output.expiresAt = value.expiresAt;
    if (typeof value.createdAt === "string")
        output.createdAt = value.createdAt;
    return output;
}
function formatPermissionDenyOnlyDiagnostics(value) {
    if (!isRecord(value))
        return {};
    const output = {};
    if (value.policyClass === "external_service_mutation") {
        output.policyClass = value.policyClass;
    }
    const riskReason = readOptionalString(value.riskReason);
    if (riskReason)
        output.riskReason = sanitizePermissionFreeformText(riskReason);
    const evidence = readStringArray(value.evidence);
    if (evidence)
        output.evidence = evidence.map(sanitizePermissionFreeformText);
    return output;
}
function readPermissionOptions(value) {
    if (!Array.isArray(value))
        return undefined;
    const options = value.filter((item) => readPermissionOption(item) !== undefined);
    return options.length > 0 ? options : undefined;
}
function isPermissionPolicyRecommendation(value) {
    return (value === "allow" ||
        value === "ask" ||
        value === "deny" ||
        value === "hard_deny");
}
function readPermissionScopeName(value) {
    if (value === "once" ||
        value === "session" ||
        value === "project" ||
        value === "always" ||
        value === "tool_class" ||
        value === "escape_hatch_run" ||
        value === "escape_hatch_project" ||
        value === "escape_hatch_global") {
        return value;
    }
    return undefined;
}
function sanitizePermissionFreeformText(value) {
    return redactPublicDiagnosticText(value)
        .replace(/\b(workspaceId|runId|sessionId|userId|runtimeSessionId|runtimeId|runtimeEventId|providerId|providerID|providerSessionId|providerRuntimeId|providerRequestId|providerPermissionId|permissionId|requestId|decisionId|sourceRuntimeEventId|decisionAuditId|auditId|revokeAuditId|sourcePermissionRequestId|commandMatchKey|commandMatcher|matcherKey|matchKey|pattern|command|modelId|modelID)\s*[:=]\s*("[^"]*"|'[^']*'|[^\s,}]+)/gi, "[redacted-internal-field]")
        .replace(/\b(runtime-session|provider-request|provider-permission|source-runtime-event|source-request|revoke-audit|audit|matcher|pattern)-[A-Za-z0-9_-]+\b/g, "[redacted-internal-id]")
        .slice(0, 500);
}
