"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WrapperFuncsVisitor = exports.WrapperVarsVisitor = void 0;
const ast_1 = require("@wapc/widl/ast");
const helpers_1 = require("./helpers");
const utils_1 = require("../utils");
class WrapperVarsVisitor extends ast_1.BaseVisitor {
    constructor(writer) {
        super(writer);
    }
    visitOperation(context) {
        if (!utils_1.shouldIncludeHandler(context)) {
            return;
        }
        if (context.config.handlerPreamble != true) {
            this.write(`var (\n`);
            context.config.handlerPreamble = true;
        }
        const operation = context.operation;
        this.write(`\t${helpers_1.uncapitalize(operation.name.value)}Handler func (${helpers_1.mapArgs(operation.arguments)}) `);
        if (!helpers_1.isVoid(operation.type)) {
            this.write(`(${helpers_1.expandType(operation.type, undefined, true, helpers_1.isReference(operation.annotations))}, error)`);
        }
        else {
            this.write(`error`);
        }
        this.write(`\n`);
    }
    visitAllOperationsAfter(context) {
        if (context.config.handlerPreamble == true) {
            this.write(`)\n\n`);
            delete context.config.handlerPreamble;
        }
        super.triggerAllOperationsAfter(context);
    }
}
exports.WrapperVarsVisitor = WrapperVarsVisitor;
class WrapperFuncsVisitor extends ast_1.BaseVisitor {
    constructor(writer) {
        super(writer);
    }
    visitOperation(context) {
        if (!utils_1.shouldIncludeHandler(context)) {
            return;
        }
        const operation = context.operation;
        this.write(`func ${helpers_1.uncapitalize(operation.name.value)}Wrapper(payload []byte) ([]byte, error) {
      decoder := msgpack.NewDecoder(payload)\n`);
        if (operation.isUnary()) {
            this.write(`var request ${helpers_1.expandType(operation.unaryOp().type, undefined, false, helpers_1.isReference(operation.annotations))}
      request.Decode(&decoder)\n`);
            this.write(helpers_1.isVoid(operation.type) ? "err := " : "response, err := ");
            this.write(`${helpers_1.uncapitalize(operation.name.value)}Handler(request)\n`);
        }
        else {
            this.write(`var inputArgs ${helpers_1.capitalize(operation.name.value)}Args
      inputArgs.Decode(&decoder)\n`);
            this.write(helpers_1.isVoid(operation.type) ? "err := " : "response, err := ");
            this.write(`${helpers_1.uncapitalize(operation.name.value)}Handler(${helpers_1.varAccessArg("inputArgs", operation.arguments)})\n`);
        }
        this.write(`if err != nil {
      return nil, err
    }\n`);
        if (helpers_1.isVoid(operation.type)) {
            this.visitWrapperBeforeReturn(context);
            this.write(`return []byte{}, nil\n`);
        }
        else if (helpers_1.isObject(operation.type)) {
            this.visitWrapperBeforeReturn(context);
            this.write(`return msgpack.ToBytes(&response)\n`);
        }
        else {
            this.write(`var sizer msgpack.Sizer
      ${helpers_1.size(true, "response", operation.type, helpers_1.isReference(operation.annotations))}
      ua := make([]byte, sizer.Len());
      encoder := msgpack.NewEncoder(ua);
      ${helpers_1.encode(true, "response", operation.type, helpers_1.isReference(operation.annotations))}\n`);
            this.visitWrapperBeforeReturn(context);
            this.write(`return ua, nil\n`);
        }
        this.write(`}\n\n`);
    }
    visitWrapperBeforeReturn(context) {
        this.triggerCallbacks(context, "WrapperBeforeReturn");
    }
}
exports.WrapperFuncsVisitor = WrapperFuncsVisitor;
//# sourceMappingURL=wrappers_visitor.js.map