"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WrappersVisitor = void 0;
const ast_1 = require("@wapc/widl/ast");
const helpers_1 = require("./helpers");
const utils_1 = require("../utils");
class WrappersVisitor extends ast_1.BaseVisitor {
    constructor(writer) {
        super(writer);
    }
    visitOperation(context) {
        if (!utils_1.shouldIncludeHandler(context)) {
            return;
        }
        const operation = context.operation;
        this.write(`var ${operation.name.value}Handler: (${helpers_1.mapArgs(operation.arguments)}) => ${helpers_1.expandType(operation.type, true, helpers_1.isReference(operation.annotations))};\n`);
        this
            .write(`function ${operation.name.value}Wrapper(payload: ArrayBuffer): ArrayBuffer {
      const decoder = new Decoder(payload)\n`);
        if (operation.isUnary()) {
            this.write(`const request = new ${helpers_1.expandType(operation.unaryOp().type, false, helpers_1.isReference(operation.annotations))}();
      request.decode(decoder);\n`);
            this.write(helpers_1.isVoid(operation.type) ? "" : "const response = ");
            this.write(`${operation.name.value}Handler(request);\n`);
        }
        else {
            this.write(`const inputArgs = new ${helpers_1.capitalize(operation.name.value)}Args();
      inputArgs.decode(decoder);\n`);
            this.write(helpers_1.isVoid(operation.type) ? "" : "const response = ");
            this.write(`${operation.name.value}Handler(${helpers_1.varAccessArg("inputArgs", operation.arguments)});\n`);
        }
        if (helpers_1.isVoid(operation.type)) {
            this.visitWrapperBeforeReturn(context);
            this.write(`return new ArrayBuffer(0);\n`);
        }
        else if (helpers_1.isObject(operation.type)) {
            this.visitWrapperBeforeReturn(context);
            this.write(`return response.toBuffer();\n`);
        }
        else {
            this.write(`const sizer = new Sizer();\n`);
            this.write(helpers_1.size("response", operation.type, helpers_1.isReference(operation.annotations)));
            this.write(`const ua = new ArrayBuffer(sizer.length);
      const encoder = new Encoder(ua);
      ${helpers_1.encode("response", operation.type, helpers_1.isReference(operation.annotations))};\n`);
            this.visitWrapperBeforeReturn(context);
            this.write(`return ua;\n`);
        }
        this.write(`}\n\n`);
    }
    visitWrapperBeforeReturn(context) {
        this.triggerCallbacks(context, "WrapperBeforeReturn");
    }
}
exports.WrappersVisitor = WrappersVisitor;
//# sourceMappingURL=wrappers_visitor.js.map