import { AnonymousAuthenticationToken } from "../Interop/types";
import { Globals } from "../../common/Globals";
import uuidv4 from "uuid-random";
import { singleton } from "../../common/Singleton";
const unknownWindowName = `Unknown window-${uuidv4()}`;
/**
 * Provides functionality related to startup of client side APIs. This runs as a singleton
 * and should always be accessed through the static method Startup.getInstance(). Never
 * construct a Startup class using new.
 */
export class Startup {
    constructor() {
        this.isReady = false;
        this.onReadyListeners = [];
        /**
         * Contains the StartupData. Default is an anonymous app.
         */
        this.currentStartupData = {
            authenticationToken: AnonymousAuthenticationToken,
            windowName: unknownWindowName,
            webContentsName: unknownWindowName,
        };
    }
    /**
     * Use this method to gain access to the Startup singleton. Never construct
     * a Startup class using new.
     * @returns Singleton instance of Startup
     */
    static getInstance() {
        if (!Startup.instance) {
            return (Startup.instance = singleton("Startup", Startup));
        }
        return Startup.instance;
    }
    /**
     * Returns the startup data that was set for this app. This data is generally
     * set in FSBL (FSBLDesktop, FSBLFreestanding, etc) and then it is cached here to
     * enable synchronous retrieval.
     *
     * Calls to System.updateOptions() or fin.Window.getCurrent().updateOptions() or finsembleWindow.updateOptions()
     * will not update this startup data!
     *
     */
    getStartupData() {
        return this.currentStartupData;
    }
    /**
     * Sets the startup data. This is typically done by FSBL (FSBLDesktop or FSBLFreestanding)
     * but is also called by System.Window.getCurrent().updateOptions.
     */
    setStartupData(newStartupData) {
        this.currentStartupData = newStartupData;
    }
    /**
     * Will trigger the listener when Finsemble's startup routine is ready. At this point it is safe
     * to use any Finsemble APIs. This guarantees:
     * a) startup data is available
     * b) router is ready to receive messages
     * c) Client APIs have been initialized
     *
     * Either pass in a callback function or await on the returned promise
     *
     * @param {() => void} [listener] Optional callback (or use await)
     */
    onReady(listener) {
        return new Promise((resolve) => {
            if (this.isReady) {
                if (listener)
                    setTimeout(listener, 0);
                resolve();
            }
            else {
                this.onReadyListeners.push(() => {
                    if (listener)
                        listener();
                    resolve();
                });
            }
        });
    }
    /**
     * This is called by "friend" modules (FSBLDesktop, FSBLService, FSBLFreestanding) when they are ready
     * for the client side API to start. This will trigger the Startup.onReady() event for any app that is
     * listening for that event.
     * @private
     */
    setReady() {
        this.isReady = true;
        this.onReadyListeners.forEach((listener) => {
            listener();
        });
        try {
            if (Globals.dispatchEvent && Globals.Event)
                Globals.dispatchEvent(new Globals.Event("FSBLReady"));
        }
        catch (e) {
            console.log(e.toString());
        }
    }
}
Startup.instance = null;
//# sourceMappingURL=Startup.js.map