import { BaseVisitor } from "@wapc/widl/ast";
import { expandType, isReference, functionName, isVoid } from "./helpers";
import { formatComment, shouldIncludeHandler } from "../utils";
export class HandlersVisitor extends BaseVisitor {
    constructor(writer) {
        super(writer);
    }
    visitOperation(context) {
        if (!shouldIncludeHandler(context)) {
            return;
        }
        if (context.config.handlerPreamble != true) {
            const className = context.config.handlersClassName || "Handlers";
            this.write(`#[cfg(feature = "guest")]
pub struct ${className} {}

#[cfg(feature = "guest")]
impl ${className} {\n`);
            context.config.handlerPreamble = true;
        }
        const operation = context.operation;
        this.write(formatComment("    /// ", operation.description));
        this.write(`pub fn register_${functionName(operation.name.value)}(f: fn(`);
        operation.arguments.forEach((arg, i) => {
            if (i > 0) {
                this.write(`, `);
            }
            this.write(expandType(arg.type, undefined, true, isReference(arg.annotations)));
        });
        this.write(`) -> HandlerResult<`);
        if (!isVoid(operation.type)) {
            this.write(`${expandType(operation.type, undefined, true, isReference(operation.annotations))}`);
        }
        else {
            this.write(`()`);
        }
        this.write(`>) {
        *${functionName(operation.name.value).toUpperCase()}.write().unwrap() = Some(f);
        register_function(&"${operation.name.value}", ${functionName(operation.name.value)}_wrapper);
    }\n`);
        super.triggerOperation(context);
    }
    visitAllOperationsAfter(context) {
        if (context.config.handlerPreamble == true) {
            this.write(`}\n\n`);
            delete context.config.handlerPreamble;
        }
        super.triggerAllOperationsAfter(context);
    }
}
//# sourceMappingURL=handlers_visitor.js.map