import { ClientIvcProof, Gas, PrivateKernelTailCircuitPublicInputs } from '@aztec/circuits.js';
import { z } from 'zod';
import { PrivateKernelProverProfileResultSchema, } from '../interfaces/private_kernel_prover.js';
import { ContractClassTxL2Logs, UnencryptedTxL2Logs } from '../logs/tx_l2_logs.js';
import { PrivateExecutionResult, collectEnqueuedPublicFunctionCalls, collectPublicTeardownFunctionCall, collectSortedContractClassLogs, } from '../private_execution_result.js';
import { NestedProcessReturnValues, PublicSimulationOutput } from './public_simulation_output.js';
import { Tx } from './tx.js';
export class PrivateSimulationResult {
    constructor(privateExecutionResult, publicInputs) {
        this.privateExecutionResult = privateExecutionResult;
        this.publicInputs = publicInputs;
    }
    getPrivateReturnValues() {
        return accumulatePrivateReturnValues(this.privateExecutionResult);
    }
    toSimulatedTx() {
        const contractClassLogs = new ContractClassTxL2Logs([collectSortedContractClassLogs(this.privateExecutionResult)]);
        const enqueuedPublicFunctions = collectEnqueuedPublicFunctionCalls(this.privateExecutionResult);
        const teardownPublicFunction = collectPublicTeardownFunctionCall(this.privateExecutionResult);
        // NB: no unencrypted logs* come from private, but we keep the property on Tx so enqueued_calls_processor.ts can accumulate public logs
        const tx = new Tx(this.publicInputs, ClientIvcProof.empty(), UnencryptedTxL2Logs.empty(), // *unencrypted logs
        contractClassLogs, enqueuedPublicFunctions, teardownPublicFunction);
        return tx;
    }
}
export class TxSimulationResult extends PrivateSimulationResult {
    constructor(privateExecutionResult, publicInputs, publicOutput, profileResult) {
        super(privateExecutionResult, publicInputs);
        this.publicOutput = publicOutput;
        this.profileResult = profileResult;
    }
    get gasUsed() {
        return (this.publicOutput?.gasUsed ?? {
            totalGas: this.publicInputs.gasUsed,
            teardownGas: Gas.empty(),
        });
    }
    static get schema() {
        return z
            .object({
            privateExecutionResult: PrivateExecutionResult.schema,
            publicInputs: PrivateKernelTailCircuitPublicInputs.schema,
            publicOutput: PublicSimulationOutput.schema.optional(),
            profileResult: PrivateKernelProverProfileResultSchema.optional(),
        })
            .transform(TxSimulationResult.from);
    }
    static from(fields) {
        return new TxSimulationResult(fields.privateExecutionResult, fields.publicInputs, fields.publicOutput, fields.profileResult);
    }
    getPublicReturnValues() {
        return this.publicOutput ? this.publicOutput.publicReturnValues : [];
    }
    static fromPrivateSimulationResultAndPublicOutput(privateSimulationResult, publicOutput, profileResult) {
        return new TxSimulationResult(privateSimulationResult.privateExecutionResult, privateSimulationResult.publicInputs, publicOutput, profileResult);
    }
    static random() {
        return new TxSimulationResult(PrivateExecutionResult.random(), PrivateKernelTailCircuitPublicInputs.empty(), PublicSimulationOutput.random());
    }
}
export class TxProvingResult {
    constructor(privateExecutionResult, publicInputs, clientIvcProof) {
        this.privateExecutionResult = privateExecutionResult;
        this.publicInputs = publicInputs;
        this.clientIvcProof = clientIvcProof;
    }
    toTx() {
        const contractClassLogs = new ContractClassTxL2Logs([collectSortedContractClassLogs(this.privateExecutionResult)]);
        const enqueuedPublicFunctions = collectEnqueuedPublicFunctionCalls(this.privateExecutionResult);
        const teardownPublicFunction = collectPublicTeardownFunctionCall(this.privateExecutionResult);
        // NB: no unencrypted logs* come from private, but we keep the property on Tx so enqueued_calls_processor.ts can accumulate public logs
        const tx = new Tx(this.publicInputs, this.clientIvcProof, UnencryptedTxL2Logs.empty(), // *unencrypted logs
        contractClassLogs, enqueuedPublicFunctions, teardownPublicFunction);
        return tx;
    }
    static get schema() {
        return z
            .object({
            privateExecutionResult: PrivateExecutionResult.schema,
            publicInputs: PrivateKernelTailCircuitPublicInputs.schema,
            clientIvcProof: ClientIvcProof.schema,
        })
            .transform(TxProvingResult.from);
    }
    static from(fields) {
        return new TxProvingResult(fields.privateExecutionResult, fields.publicInputs, fields.clientIvcProof);
    }
    static random() {
        return new TxProvingResult(PrivateExecutionResult.random(), PrivateKernelTailCircuitPublicInputs.empty(), ClientIvcProof.empty());
    }
}
/**
 * Recursively accummulate the return values of a call result and its nested executions,
 * so they can be retrieved in order.
 * @param executionResult
 * @returns
 */
export function accumulatePrivateReturnValues(executionResult) {
    const acc = new NestedProcessReturnValues(executionResult.returnValues);
    acc.nested = executionResult.nestedExecutions.map(nestedExecution => accumulatePrivateReturnValues(nestedExecution));
    return acc;
}
//# sourceMappingURL=data:application/json;base64, 