import * as nodePath from 'path';
import { ApplicationEngine } from './ApplicationEngine';
import { SnapshotHandler } from './SnapshotHandler';
import { constants, createCSharpDispatchInvoke, validateProtocolSettings } from './utils';
const engineAssemblyOptions = {
    assemblyFile: nodePath.join(constants.CSHARP_APP_ROOT, 'Dispatcher.dll'),
    methodName: 'Invoke',
    typeName: 'NEOONE.Dispatcher',
};
export const createDispatcher = () => createCSharpDispatchInvoke(engineAssemblyOptions);
export class Dispatcher {
    constructor(options = {}) {
        this.options = options;
        this.dispatch = createDispatcher();
        this.init = this.initialize(this.options.levelDBPath, this.options.protocolSettings);
    }
    withSnapshots(func) {
        const main = new SnapshotHandler(this, 'main');
        const clone = new SnapshotHandler(this, 'clone');
        return func({ main, clone });
    }
    withApplicationEngine(options, func) {
        const engine = new 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 ? validateProtocolSettings(settings) : undefined,
            },
        });
    }
}

//# sourceMappingURL=Dispatcher.js.map
