<!doctype html>
<html lang="en">
<head>
   <meta charset="utf-8">
   <meta name="viewport" content="width=device-width, initial-scale=1">
   <title>Hypha App Template</title>
   <meta name="description" content="Template for Hypha app">
   <meta name="author" content="ImJoy-Team">
   <script src="https://cdn.jsdelivr.net/npm/imjoy-core@0.13.82/src/pluginParser.js"></script>
</head>

<body>
    <script type="module">
        function randId() {
            return (
                Math.random()
                .toString(36)
                .substr(2, 5) + Date.now()
            );
        }
        const CONFIGURABLE_FIELDS = [
            "env",
            "requirements",
            "dependencies",
            "icon",
            "ui",
            "type",
            "flags",
            "labels",
            "cover",
            "base_frame",
            "base_worker",
            "passive",
        ];
        const config = Object.fromEntries(new URLSearchParams(window.location.search))
        if(!config.server_url) config.server_url = window.location.origin;
        const hyphaWebsocketClient = await import(config.server_url + '/assets/hypha-rpc-websocket.mjs');
        const api = await hyphaWebsocketClient.connectToServer(config)
        const pluginParser = await import("https://cdn.jsdelivr.net/npm/imjoy-core@0.13.82/src/pluginParser.js")
        function parsePluginCode(code, overwrite_config) {
            overwrite_config = overwrite_config || {};
            try {
                const pluginComp = pluginParser.parseComponent(code);
                let config;
                if (pluginComp.config[0].attrs.lang === "yaml") {
                    throw new Error("YAML not supported")
                    // config = yaml.load(pluginComp.config[0].content);
                } else if (pluginComp.config[0].attrs.lang === "json") {
                    config = JSON.parse(pluginComp.config[0].content);
                } else {
                    config = JSON.parse(pluginComp.config[0].content);
                    if (compareVersions(config.api_version, ">", "0.1.5")) {
                    throw `Unsupported config language ${
                        pluginComp.config[0].attrs.lang
                    }, please set lang="json" or lang="yaml"`;
                    }
                }

                config.tag = overwrite_config.tag || (config.tags && config.tags[0]);
                (config.hot_reloading = overwrite_config.hot_reloading),
                    (config.scripts = []);
                // try to match the script with current tag
                for (let i = 0; i < pluginComp.script.length; i++) {
                    if (pluginComp.script[i].attrs.tag === config.tag) {
                    config.script = pluginComp.script[i].content;
                    }

                    // exclude script with mismatched tag
                    if (
                    !pluginComp.script[i].attrs.tag ||
                    pluginComp.script[i].attrs.tag === config.tag
                    ) {
                    config.scripts.push(pluginComp.script[i]);
                    }
                }
                if (!config.script && pluginComp.script.length > 0) {
                    config.script = pluginComp.script[0].content;
                    config.lang = pluginComp.script[0].attrs.lang;
                }
                config.links = pluginComp.link || null;
                config.windows = pluginComp.window || null;
                config.styles = pluginComp.style || null;
                config.docs = (pluginComp.docs && pluginComp.docs[0]) || config.docs;
                config.attachments = pluginComp.attachment || null;

                config._id = overwrite_config._id || config.name.replace(/ /g, "_");
                config.uri = overwrite_config.uri;
                config.origin = overwrite_config.origin;
                config.namespace = overwrite_config.namespace;
                config.code = code;
                config.id = config.name.trim().replace(/ /g, "_") + "_" + randId();
                config.runnable = config.runnable === false ? false : true;
                config.requirements = config.requirements || [];

                for (let i = 0; i < CONFIGURABLE_FIELDS.length; i++) {
                    const obj = config[CONFIGURABLE_FIELDS[i]];
                    if (obj && typeof obj === "object" && !(obj instanceof Array)) {
                    if (config.tag) {
                        config[CONFIGURABLE_FIELDS[i]] = obj[config.tag];
                        if (!Object.prototype.hasOwnProperty.call(obj, config.tag)) {
                        console.log(
                            "WARNING: " +
                            CONFIGURABLE_FIELDS[i] +
                            " do not contain a tag named: " +
                            config.tag
                        );
                        }
                    } else {
                        throw "You must use 'tags' with configurable fields.";
                    }
                    }
                }
                config.lang = config.lang || "javascript";
                
                return config;
            } catch (e) {
                console.error(e);
                throw `Failed to parse the plugin file, error: ${e}`;
            }
        }
        function setup(){
            
        }
        await api.export({setup, parsePluginCode})
    </script>
</body>
</html>