import { BaseVisitor } from "@wapc/widl/ast";
import { shouldIncludeHandler } from "../utils";
import { defaultValueForType, expandType, functionName, isReference, isVoid, mapArgs, } from "./helpers";
export class ScaffoldVisitor extends BaseVisitor {
    constructor(writer) {
        super(writer);
    }
    visitDocumentBefore(context) {
        const useName = context.config["use"] || "generated";
        super.visitDocumentBefore(context);
        this.write(`mod ${useName};
extern crate wapc_guest as guest;
use guest::prelude::*;
pub use ${useName}::*;\n\n`);
    }
    visitAllOperationsBefore(context) {
        const registration = new HandlerRegistrationVisitor(this.writer);
        context.document.accept(context, registration);
    }
    visitOperation(context) {
        if (!shouldIncludeHandler(context)) {
            return;
        }
        const operation = context.operation;
        this.write(`\n`);
        this.write(`fn ${functionName(operation.name.value)}(${mapArgs(operation.arguments, true)}) -> HandlerResult<`);
        if (!isVoid(operation.type)) {
            this.write(expandType(operation.type, undefined, true, isReference(operation.annotations)));
        }
        else {
            this.write(`()`);
        }
        this.write(`> {\n`);
        if (!isVoid(operation.type)) {
            const dv = defaultValueForType(operation.type, undefined);
            this.write(`    Ok(${dv})`);
        }
        else {
            this.write(`    Ok(())`);
        }
        this.write(` // TODO: Provide implementation.\n`);
        this.write(`}\n`);
    }
}
class HandlerRegistrationVisitor extends BaseVisitor {
    constructor(writer) {
        super(writer);
    }
    visitAllOperationsBefore(context) {
        this.write(`#[no_mangle]
pub fn wapc_init() {\n`);
    }
    visitOperation(context) {
        if (!shouldIncludeHandler(context)) {
            return;
        }
        const operation = context.operation;
        this.write(`    Handlers::register_${functionName(operation.name.value)}(${functionName(operation.name.value)});\n`);
    }
    visitAllOperationsAfter(context) {
        this.write(`}\n`);
    }
}
//# sourceMappingURL=scaffold_visitor.js.map