/*!
 * Copyright 2017 - 2020 by ChartIQ, Inc.
 * All rights reserved.
 */
// TestPoint is currently located in common but accessible on FSBL for Live-Mocha testing.
import { RouterClient } from "../clients/routerClient";
import { Logger } from "../clients/logger";
const TestPointChannel = "Finsemble.testPointsEnabled";
const TestPointActionChannel = "Finsemble.testPointActions";
const SnapshotPointWaitTimeout = 60 * 1000;
/**
 * Singleton API to Finsemble System Manager
 */
class TestPoint {
    constructor() {
        this.testPointsEnabled = false;
        this.actionMap = {};
        // State made accessable for TestPoint clients to directly access and store data within.
        this.state = {};
        this.start();
    }
    async start() {
        RouterClient.addListener(TestPointChannel, () => {
            Logger.system.debug(`TestPoint Module Enable`);
            this.testPointsEnabled = true;
        });
        RouterClient.addListener(TestPointActionChannel, (err, response) => {
            let { name, data } = response.data;
            if (this.testPointsEnabled && typeof this.actionMap[name] === "function") {
                Logger.system.debug(`TestPoint: firing ${name} action`, data);
                this.actionMap[name](data);
            }
        });
    }
    /**
     * Enables testpoints.  Must be invoked once from somewhere in Finsemble for testpoints to work.  Can be involved multiple times.
     *
     * @memberof TestPoint
     */
    enableTestPoints() {
        RouterClient.transmit(TestPointChannel, true);
    }
    /**
     * Triggers a specific snapshot, capturing the data to be returned by waitForSnapshot for the given snapshot name
     *
     * @param {string} name snapshot name
     * @param {*} snapshotData data
     * @memberof TestPoint
     */
    triggerSnapshot(name, snapshotData) {
        if (this.testPointsEnabled) {
            RouterClient.transmit("Finsemble.testPoint", { name, snapshotData });
            Logger.system.debug("forceObjectsToLogger", `TestPoint: generating snapshot ${name}`, snapshotData);
        }
    }
    /**
     * Waits for a specific snapshot point to be reached from somewhere in Finsemble, then returns the snapshot data.
     *
     * @param {*} snapshotName snapshot name to wait for
     * @param {number} [count=1] the number of times the testpoint name must be triggered before returning
     * @param {*} [timeout=SnapshotPointWaitTimeout] How long in milliseconds to wait before failing
     * @returns
     * @memberof TestPoint
     */
    waitForSnapshot(snapshotName, count = 1, timeout = SnapshotPointWaitTimeout) {
        let counter = 0;
        return new Promise((resolve) => {
            let timeoutId = setTimeout(() => {
                Logger.system.error(`waitForSnapshot timed out on ${snapshotName}`);
                resolve(null);
            }, timeout);
            RouterClient.addListener("Finsemble.testPoint", (err, response) => {
                if (response.data.name === snapshotName && ++counter === count) {
                    clearTimeout(timeoutId);
                    Logger.system.debug("forceObjectsToLogger", `TestPoint: waitForSnapshot ${snapshotName} resolving`, response.data.snapshotData);
                    resolve(response.data.snapshotData);
                }
            });
        });
    }
    /**
     * Fires customized test action(s) corresponding to specified name -- causes the correspond onAction() to be triggered.
     * Typically used within a Live Mocha test.
     *
     * @param name name of action to fire
     * @param data data to pass to action
     */
    triggerAction(name, data) {
        RouterClient.transmit(TestPointActionChannel, { name, data });
        Logger.system.debug("forceObjectsToLogger", `TestPoint: triggerAction ${name}`, data);
    }
    /**
     * Used to implement customized actions for the specificed name -- the callback is invoked when a corresponding triggerAction() is called.
     * Typically used within unit under test to set test state or simulate user actions.
     *
     * @param name name of action to look for
     * @param callback function to invoke when action fires
     */
    onAction(name, callback) {
        Logger.system.debug("forceObjectsToLogger", `TestPoint: onAction defined ${name}`);
        this.actionMap[name] = callback;
    }
}
const testPoint = new TestPoint();
export default testPoint;
//# sourceMappingURL=testPoint.js.map