"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.DebuggerClient = void 0;
const debugger_worker_1 = require("./debugger-worker");
const types_1 = require("./types");
class DebuggerClient {
    constructor(useWebWorker = false, worker) {
        this.seq = 0;
        if (useWebWorker) {
            this.worker = worker !== null && worker !== void 0 ? worker : new Worker("./worker/dist/truffle-debugger-worker.js");
        }
        else {
            this.worker = new debugger_worker_1.DebuggerWorker();
        }
        this.initialized = false;
        this.resolverMap = new Map();
        this.worker.onmessage = (ev) => {
            this.handleResponse(ev.data);
        };
    }
    initialize(init_arguments) {
        return __awaiter(this, void 0, void 0, function* () {
            yield this.sendRequest(types_1.Command.Initialize, init_arguments);
        });
    }
    stepOver() {
        return __awaiter(this, void 0, void 0, function* () {
            return yield this.sendRequest(types_1.Command.StepOver);
        });
    }
    stepInto() {
        return __awaiter(this, void 0, void 0, function* () {
            return yield this.sendRequest(types_1.Command.StepInto);
        });
    }
    stepOut() {
        return __awaiter(this, void 0, void 0, function* () {
            return yield this.sendRequest(types_1.Command.StepOut);
        });
    }
    stepNext() {
        return __awaiter(this, void 0, void 0, function* () {
            return yield this.sendRequest(types_1.Command.StepOut);
        });
    }
    advance() {
        return __awaiter(this, void 0, void 0, function* () {
            return yield this.sendRequest(types_1.Command.StepInstruction);
        });
    }
    continueUntilBreakpoint() {
        return __awaiter(this, void 0, void 0, function* () {
            return yield this.sendRequest(types_1.Command.ContinueUntilBreakpoint);
        });
    }
    addBreakpoint(breakpoint) {
        return __awaiter(this, void 0, void 0, function* () {
            yield this.sendRequest(types_1.Command.AddBreakpoint, breakpoint);
        });
    }
    removeBreakpoint(breakpoint) {
        return __awaiter(this, void 0, void 0, function* () {
            yield this.sendRequest(types_1.Command.RemoveAllBreakpoints, breakpoint);
        });
    }
    removeAllBreakpoints() {
        return __awaiter(this, void 0, void 0, function* () {
            yield this.sendRequest(types_1.Command.RemoveAllBreakpoints);
        });
    }
    requireVariables() {
        return __awaiter(this, void 0, void 0, function* () {
            return yield this.sendRequest(types_1.Command.Variables);
        });
    }
    requireStacktrace() {
        return __awaiter(this, void 0, void 0, function* () {
            return yield this.sendRequest(types_1.Command.Stacktrace);
        });
    }
    sendRequest(command, args) {
        const request = {
            command: command,
            seq: this.seq,
            arguments: args,
            type: "request"
        };
        this.worker.postMessage(request);
        return new Promise((resolve, reject) => {
            this.resolverMap.set(this.seq, resolve);
            this.seq++;
        });
    }
    handleResponse(resp) {
        if (resp.command === types_1.Command.Initialize) {
            this.initialized = true;
        }
        if (this.resolverMap.has(resp.request_seq)) {
            this.resolverMap.get(resp.request_seq)(resp.body);
            this.resolverMap.delete(resp.request_seq);
        }
    }
}
exports.DebuggerClient = DebuggerClient;
//# sourceMappingURL=debugger-client.js.map