import { BaseVisitor, ObjectDefinition, FieldDefinition, Name, } from "@wapc/widl/ast";
import { capitalize } from "./helpers";
import { StructVisitor } from "./struct_visitor";
import { HostVisitor } from "./host_visitor";
import { HandlersVisitor, RegisterVisitor } from "./handlers_visitor";
import { WrapperVarsVisitor, WrapperFuncsVisitor } from "./wrappers_visitor";
export class ModuleVisitor extends BaseVisitor {
    constructor(writer) {
        super(writer);
        this.setCallback("AllOperationsBefore", "host", (context) => {
            const host = new HostVisitor(writer);
            context.document.accept(context, host);
        });
        this.setCallback("AllOperationsBefore", "handlers", (context) => {
            const handlers = new HandlersVisitor(this.writer);
            context.document.accept(context, handlers);
            const register = new RegisterVisitor(this.writer);
            context.document.accept(context, register);
        });
        this.setCallback("AllOperationsBefore", "wrappers", (context) => {
            const wrapperVars = new WrapperVarsVisitor(this.writer);
            context.document.accept(context, wrapperVars);
            const wrapperFuncs = new WrapperFuncsVisitor(this.writer);
            context.document.accept(context, wrapperFuncs);
        });
        this.setCallback("OperationAfter", "arguments", (context) => {
            if (context.operation.isUnary()) {
                return;
            }
            const argObject = this.convertOperationToObject(context.operation);
            const struct = new StructVisitor(this.writer);
            argObject.accept(context.clone({ object: argObject }), struct);
        });
        this.setCallback("Object", "struct", (context) => {
            const struct = new StructVisitor(this.writer);
            context.object.accept(context, struct);
        });
    }
    visitDocumentBefore(context) {
        const packageName = context.config["package"] || "module";
        this.write(`package ${packageName}\n`);
        this.write(`\n`);
        this.write(`import (\n`);
        this.write(`\twapc "github.com/wapc/wapc-guest-tinygo"\n`);
        this.write(`\tmsgpack "github.com/wapc/tinygo-msgpack"\n`);
        this.write(`)\n\n`);
        super.triggerDocumentBefore(context);
    }
    convertOperationToObject(operation) {
        var fields = operation.arguments.map((arg) => {
            return new FieldDefinition(arg.loc, arg.name, arg.description, arg.type, arg.default, arg.annotations);
        });
        return new ObjectDefinition(operation.loc, new Name(operation.name.loc, capitalize(operation.name.value) + "Args"), undefined, [], operation.annotations, fields);
    }
}
//# sourceMappingURL=module_visitor.js.map