"use strict";
/*
 * @adonisjs/repl
 *
 * (c) Harminder Virk <virk@adonisjs.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.Compiler = void 0;
const node_repl_await_1 = require("node-repl-await");
const ImportsParser_1 = require("../ImportsParser");
/**
 * Exposes the API to compile the user land code to be executed
 * inside Node.JS REPL.
 */
class Compiler {
    constructor(tsCompiler) {
        this.tsCompiler = tsCompiler;
        this.compilesTs = !!this.tsCompiler;
    }
    /**
     * Process the await keywords in the code
     */
    processAwait(statement) {
        const potentialWrappedCode = (0, node_repl_await_1.processTopLevelAwait)(statement);
        if (!potentialWrappedCode) {
            return { compiled: statement, awaitPromise: false };
        }
        return { compiled: potentialWrappedCode, awaitPromise: true };
    }
    /**
     * Compiles code using typescript
     */
    async compileTypescript(statement, filename) {
        const lines = statement.split(/\n|\r\n/);
        let compiledOutput = statement;
        /**
         * In case of a single line, we process the import
         * keywords and define local variables to hold
         * the import reference
         */
        if (lines.length <= 2) {
            compiledOutput = await new ImportsParser_1.ImportsParser().parse(statement);
        }
        /**
         * Compile using typescript compiler and patch the
         * `sourceMappingUrl` comment to be a block level comment.
         */
        compiledOutput = this.tsCompiler.compile(filename, compiledOutput, true);
        return `${compiledOutput.replace('//# sourceMappingURL=', '/**# sourceMappingURL=')} */`;
    }
    /**
     * Compiles the code to be executed in the Node.js REPL. Under
     * the hood
     *
     * - Typescript code is compiled
     * - Await keywords are wrapped in async IIFE
     */
    async compile(statement, filename) {
        if (this.tsCompiler) {
            statement = await this.compileTypescript(statement, filename);
        }
        return this.processAwait(statement);
    }
}
exports.Compiler = Compiler;
