import { DataverseKernel, } from "@dataverse/dataverse-kernel";
import { Communicator } from "@meteor-web3/communicator";
import localforage from "localforage";
import { ExternalWallet } from "./wallet/external-wallet";
let walletInstance;
let communicator;
const serializeHostWallet = () => {
    const hostWallet = DataverseKernel.instance.drivers.cryptoWallet.hostWallet.hostWallet;
    const hostWalletKeys = Object.keys(hostWallet);
    const serializableObject = {
        keys: hostWalletKeys,
    };
    const serializedString = JSON.stringify(serializableObject);
    localStorage.setItem("hostWalletCache", serializedString);
    // console.log("set hostWalletCache", {
    //   serializableObject,
    //   serializedString,
    // });
};
const deserializeHostWallet = () => {
    const hostWalletCache = localStorage.getItem("hostWalletCache");
    // console.log("get hostWalletCache", { hostWalletCache });
    if (hostWalletCache) {
        const { keys } = JSON.parse(hostWalletCache);
        walletInstance = new ExternalWallet();
        keys.forEach((key) => {
            DataverseKernel.instance.drivers.cryptoWallet.hostWallet.hostWallet[key] =
                [{ wallet: walletInstance, isCurrent: true }];
        });
        // console.log(
        //   "hostWallet",
        //   DataverseKernel.instance.drivers.cryptoWallet.hostWallet.hostWallet,
        // );
    }
};
const versionCheck = () => {
    const METEOR_IFRAME_VERSION = localStorage.getItem("METEOR_IFRAME_VERSION");
    if (!METEOR_IFRAME_VERSION ||
        METEOR_IFRAME_VERSION !== process.env.PACKAGE_VERSION) {
        localStorage.clear();
        indexedDB.deleteDatabase("localforage");
        localStorage.setItem("METEOR_IFRAME_VERSION", process.env.PACKAGE_VERSION);
        return true;
    }
    return false;
};
class LocalStorageProvider {
    localforage = localforage.createInstance({
        driver: localforage.LOCALSTORAGE,
    });
    setItem(key, val) {
        return this.localforage.setItem(key, val);
    }
    getItem(key) {
        return this.localforage.getItem(key);
    }
    getKeys() {
        return this.localforage.keys();
    }
    removeItem(key) {
        return this.localforage.removeItem(key);
    }
    clear() {
        return this.localforage.clear();
    }
}
export function injectKernel() {
    // console.log({
    //   env: process.env,
    //   DATAVERSE: process.env.DATAVERSE,
    // });
    // check version
    const clearedCache = versionCheck();
    // check if brave
    const isBrave = !!navigator.brave;
    console.log({
        isBrave,
        METEOR_IFRAME_VERSION: process.env.PACKAGE_VERSION,
        clearedCache,
    });
    if (!DataverseKernel.instance) {
        DataverseKernel.init(isBrave
            ? {
                localStorageProvider: new LocalStorageProvider(),
            }
            : undefined);
        // console.log("DataverseKernel init finished.");
    }
    deserializeHostWallet();
    if (!walletInstance) {
        walletInstance = new ExternalWallet();
        // console.log("ExternalWallet init finished.");
    }
    if (!communicator) {
        communicator = new Communicator({
            source: window,
            target: window.top,
            runningEnv: "Kernel",
            methodHandler: async (args, event) => {
                // console.log("Kernel => onHandleMethod", args);
                let res;
                if (args.method === "connectWallet") {
                    // only ExternalWallet is supported in Iframe
                    res = await DataverseKernel.instance.eventListener.connectWallet({
                        ...args.params,
                        walletInstance,
                    }, { origin: event.origin });
                    serializeHostWallet();
                }
                else {
                    // check if connected wallet
                    const currentWallet = await DataverseKernel.instance.drivers.cryptoWallet.hostWallet.getCurrentWalletByHost(event.origin);
                    if (!currentWallet) {
                        // connect wallet first
                        await DataverseKernel.instance.eventListener.connectWallet({
                            walletInstance,
                        }, { origin: event.origin });
                        serializeHostWallet();
                    }
                    res = await DataverseKernel.instance.eventListener[args.method](args.params, { origin: event.origin });
                }
                // console.log("Kernel => onHandleMethod => return", args);
                return res;
            },
        });
        // console.log("Communicator init finished.");
    }
    window.top?.postMessage({ type: "METEOR_IFRAME_READY" }, "*");
}
