"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.switchCoreTransport = exports.init = void 0;
const hardware_transport_http_1 = require("@ukeyfe/hardware-transport-http");
const hardware_transport_emulator_1 = require("@ukeyfe/hardware-transport-emulator");
const hardware_transport_web_device_1 = require("@ukeyfe/hardware-transport-web-device");
const hardware_core_1 = require("@ukeyfe/hardware-core");
const lodash_1 = require("lodash");
const urlUtils_1 = require("../utils/urlUtils");
const bridgeUtils_1 = require("../utils/bridgeUtils");
const bridge_config_1 = require("./bridge-config");
const __1 = require("..");
let _core;
const Log = (0, hardware_core_1.getLogger)(hardware_core_1.LoggerNames.Iframe);
const getTransport = (env) => {
    if (env === 'webusb' || env === 'desktop-webusb')
        return hardware_transport_web_device_1.WebUsbTransport;
    if (env === 'emulator')
        return hardware_transport_emulator_1.default;
    return hardware_transport_http_1.default;
};
const handleMessage = (event) => {
    var _a;
    if (event.source === window || !event.data)
        return;
    const whitelist = (0, __1.isOriginWhitelisted)(event.origin) || (0, __1.isExtensionWhitelisted)(event.origin);
    const isTrustedDomain = event.origin === window.location.origin || !!whitelist;
    const eventOrigin = (0, urlUtils_1.getOrigin)(event.origin);
    if (!isTrustedDomain &&
        eventOrigin !== hardware_core_1.DataManager.getSettings('origin') &&
        eventOrigin !== (0, urlUtils_1.getOrigin)(document.referrer)) {
        return;
    }
    const message = (0, hardware_core_1.parseMessage)(event);
    if (message.type === hardware_core_1.IFRAME.INIT) {
        init((_a = message.payload) !== null && _a !== void 0 ? _a : {});
    }
};
function init(payload) {
    var _a;
    return __awaiter(this, void 0, void 0, function* () {
        if (hardware_core_1.DataManager.getSettings('origin'))
            return;
        const settings = (0, hardware_core_1.parseConnectSettings)(Object.assign(Object.assign({}, ((_a = payload.settings) !== null && _a !== void 0 ? _a : {})), { isFrame: true }));
        settings.origin = !origin || origin === 'null' ? payload.settings.origin : origin;
        Log.enabled = !!settings.debug;
        try {
            const Transport = getTransport(settings.env);
            _core = yield (0, hardware_core_1.initCore)(settings, Transport);
            _core === null || _core === void 0 ? void 0 : _core.on(hardware_core_1.CORE_EVENT, messages => (0, bridgeUtils_1.sendMessage)(messages, false));
        }
        catch (error) {
            return (0, hardware_core_1.createErrorMessage)(error);
        }
        (0, bridgeUtils_1.createJsBridge)({
            isHost: false,
            remoteFrame: window.parent,
            remoteFrameName: bridge_config_1.default.hostName,
            selfFrameName: bridge_config_1.default.iframeName,
            channel: bridge_config_1.default.channel,
            targetOrigin: (0, urlUtils_1.getOrigin)(settings.parentOrigin),
            receiveHandler: (messageEvent) => __awaiter(this, void 0, void 0, function* () {
                const message = (0, hardware_core_1.parseMessage)(messageEvent);
                const blockLog = hardware_core_1.LogBlockEvent.has((0, lodash_1.get)(message, 'type')) ? message.type : undefined;
                if (blockLog) {
                    Log.debug('Frame Bridge Receive message: ', blockLog);
                }
                else {
                    Log.debug('Frame Bridge Receive message: ', message);
                }
                if (message.event === hardware_core_1.IFRAME.SWITCH_TRANSPORT) {
                    Log.debug('switchCoreTransport', message.payload.env);
                    (0, exports.switchCoreTransport)(message.payload.env);
                    return { success: true, payload: {} };
                }
                const response = yield (_core === null || _core === void 0 ? void 0 : _core.handleMessage(message));
                if (blockLog) {
                    Log.debug('Frame Bridge response message: ', blockLog);
                }
                else {
                    Log.debug('Frame Bridge response message: ', message);
                }
                return response;
            }),
        });
        yield (0, bridgeUtils_1.sendMessage)((0, hardware_core_1.createIFrameMessage)(hardware_core_1.IFRAME.INIT_BRIDGE, {}), false);
    });
}
exports.init = init;
const switchCoreTransport = (env) => {
    if (_core) {
        const Transport = getTransport(env);
        (0, hardware_core_1.switchTransport)({
            env,
            Transport,
        });
    }
};
exports.switchCoreTransport = switchCoreTransport;
window.addEventListener('message', handleMessage, false);
//# sourceMappingURL=index.js.map