"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Dispatcher = exports.createDispatcher = void 0;
const tslib_1 = require("tslib");
const nodePath = tslib_1.__importStar(require("path"));
const ApplicationEngine_1 = require("./ApplicationEngine");
const SnapshotHandler_1 = require("./SnapshotHandler");
const utils_1 = require("./utils");
const engineAssemblyOptions = {
    assemblyFile: nodePath.join(utils_1.constants.CSHARP_APP_ROOT, 'Dispatcher.dll'),
    methodName: 'Invoke',
    typeName: 'NEOONE.Dispatcher',
};
exports.createDispatcher = () => utils_1.createCSharpDispatchInvoke(engineAssemblyOptions);
class Dispatcher {
    constructor(options = {}) {
        this.options = options;
        this.dispatch = exports.createDispatcher();
        this.init = this.initialize(this.options.levelDBPath, this.options.protocolSettings);
    }
    withSnapshots(func) {
        const main = new SnapshotHandler_1.SnapshotHandler(this, 'main');
        const clone = new SnapshotHandler_1.SnapshotHandler(this, 'clone');
        return func({ main, clone });
    }
    withApplicationEngine(options, func) {
        const engine = new ApplicationEngine_1.ApplicationEngine(this);
        engine.create(options);
        let result;
        try {
            result = func(engine);
        }
        catch (error) {
            throw error;
        }
        finally {
            this.disposeEngine();
        }
        return result;
    }
    disposeEngine() {
        this.dispatch({
            method: 'dispose_engine',
        });
    }
    updateSnapshots() {
        this.dispatch({
            method: 'snapshot_reset',
        });
    }
    dispose() {
        this.dispatch({
            method: 'dispose',
        });
    }
    reset() {
        this.dispose();
        this.initialize(this.options.levelDBPath);
    }
    getConfig() {
        return this.dispatch({
            method: 'get_config',
        });
    }
    updateSnapshot(key, id, value) {
        return this.dispatch({
            method: 'test_snapshot_add',
            args: {
                key,
                id,
                value,
            },
        });
    }
    readSnapshot(key, id) {
        return this.dispatch({
            method: 'test_snapshot_get',
            args: {
                key,
                id,
            },
        });
    }
    updateStore(storage) {
        this.dispatch({
            method: 'test_update_store',
            args: {
                changes: storage,
            },
        });
    }
    readStore(key) {
        return this.dispatch({
            method: 'test_read_store',
            args: {
                key,
            },
        });
    }
    test() {
        return this.dispatch({
            method: 'test',
        });
    }
    initialize(path, settings) {
        return this.dispatch({
            method: 'init',
            args: {
                path,
                settings: settings ? utils_1.validateProtocolSettings(settings) : undefined,
            },
        });
    }
}
exports.Dispatcher = Dispatcher;

//# sourceMappingURL=Dispatcher.js.map
