var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
    if (kind === "m") throw new TypeError("Private method is not writable");
    if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
    if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
    return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
};
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
    if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
    if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
    return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var _FSBLFreestanding_fdc3;
import { RouterController } from "../routerClient";
import { Startup } from "../Startup/Startup";
import { getRouterConfig } from "./RouterConfig";
import { LoggerClient as Logger } from "../logger";
import { authSignature } from "../../platform/services/Interop/AuthSignVerify";
import uuidv4 from "uuid-random";
/**
 * Starts Finsemble for "freestanding" apps (those that are not running under Electron). This is used
 * by the finsemble-javascript-adapter.
 */
export class FSBLFreestanding {
    constructor({ fdc3 }) {
        _FSBLFreestanding_fdc3.set(this, void 0);
        __classPrivateFieldSet(this, _FSBLFreestanding_fdc3, fdc3, "f");
        console.log("Finsemble JavaScript Adapter for FDC3 2.0");
    }
    /**
     * Freestanding apps must call startApp() to start the FSBL and fdc3 client code.
     *
     * Startup configurations and data can be passed in the params. If not provided, defaults will be used
     * according to the typedocs for StartupData.
     */
    async startApp(params) {
        var _a, _b, _c, _d, _e;
        // Window name must be unique within Finsemble, so uuid is always added even if passed in params.
        // This also prevents a freestanding app from spoofing another window by taking its name.
        const windowName = `${(_c = (_a = params === null || params === void 0 ? void 0 : params.windowName) !== null && _a !== void 0 ? _a : (_b = document === null || document === void 0 ? void 0 : document.location) === null || _b === void 0 ? void 0 : _b.href) !== null && _c !== void 0 ? _c : "freestandingApp"}-${uuidv4()}`;
        // If no appName is provided then use the windowName. The app will be treated anonymously.
        const appName = (_d = params === null || params === void 0 ? void 0 : params.appName) !== null && _d !== void 0 ? _d : windowName;
        const appId = (_e = params === null || params === void 0 ? void 0 : params.appId) !== null && _e !== void 0 ? _e : appName;
        let authenticationToken;
        // If JSON Web Token is passed in then use it in place of the digital signing key. The use case is for the JWT to be created on a server to avoid having to include the private key into the app.
        // Note that Finsemble will use JWT's iot field to internally set the token's timestamp -- the Finsemble TTL for a token is 30 seconds.
        // JWT optional expiration time is not used to avoid confusion with the static auth timestamp, plus JWT expiration times are typically in minutes, where Finsemble needs to enforce a short TTL.
        if (params === null || params === void 0 ? void 0 : params.jwt) {
            authenticationToken = {
                signatureStringType: "static-jwt",
                signatureString: params === null || params === void 0 ? void 0 : params.jwt,
                meta: {
                    appId: appId,
                    name: appName,
                },
            };
            //else if digital signing key provided, then creates the static AuthenticationToken that is necessary to instantiate interop.
        }
        else if (params === null || params === void 0 ? void 0 : params.digitalSigningKey) {
            authenticationToken = await this.staticAuthenticationToken(params === null || params === void 0 ? void 0 : params.digitalSigningKey, appName);
        }
        else {
            // If a digital signing key hasn't been provided then the default is used with type set to "unauthenticated".
            authenticationToken = {
                signatureStringType: "unauthenticated",
                signatureString: "",
                meta: {
                    name: appName,
                    appId, // authentication is based on the appId
                },
            };
        }
        /**
         * Finsemble's router client requires a windowName but otherwise it will start with defaults unless routerAddress
         * has been set, in which case that will be set as the serverAddress for IAC (FinsembleTransport).
         */
        const routerAddress = params === null || params === void 0 ? void 0 : params.routerAddress;
        const definitiveRouterConfig = getRouterConfig(routerAddress
            ? {
                windowName,
                transportSettings: {
                    FinsembleTransport: {
                        serverAddress: routerAddress,
                    },
                },
            }
            : {
                windowName,
            });
        const definitiveStartupData = {
            windowName,
            webContentsName: windowName,
            authenticationToken,
        };
        const startup = Startup.getInstance();
        startup.setStartupData(definitiveStartupData);
        await RouterController.start(definitiveRouterConfig);
        startup.setReady();
        Logger.start();
        // In freestanding apps, we always immediately connect to the interop service.
        __classPrivateFieldGet(this, _FSBLFreestanding_fdc3, "f").start();
    }
    /**
     * Builds and returns a static authentication token.
     */
    async staticAuthenticationToken(digitalSigningKey, name) {
        // a timestamp is in the signed data, which will be used for TTL check
        const timestamp = Date.now();
        const signatureData = { timestamp };
        const { signature } = await authSignature(digitalSigningKey, signatureData);
        return {
            signatureStringType: "static",
            timestamp,
            signatureString: signature,
            meta: {
                name,
                appId: name,
            },
        };
    }
    /**
     * Stops the app.
     */
    async stopApp() {
        __classPrivateFieldGet(this, _FSBLFreestanding_fdc3, "f").stop();
        Logger.unregisterClient();
        RouterController.stop();
    }
}
_FSBLFreestanding_fdc3 = new WeakMap();
//# sourceMappingURL=FSBLFreestanding.js.map