text: import {bdpluginErrors, pluginCookie, settingsCookie, bdplugins} from "../0globals";
  import ContentManager from "./contentManager";
  import DataStore from "./dataStore";
  import BDEvents from "./bdEvents";
  import Utils from "./utils";
  
  class PluginModule {
      constructor(){
          window.Lightcord.BetterDiscord.PluginModule = this
      }
      get folder() {return ContentManager.pluginsFolder;}
  }
  
  PluginModule.prototype.loadPlugins = async function () {
      this.loadPluginData();
      bdpluginErrors.splice(0, 0, ...(await ContentManager.loadPlugins()));
      const plugins = Object.keys(bdplugins);
      for (let i = 0; i < plugins.length; i++) {
          let plugin, name;
  
          try {
              plugin = bdplugins[plugins[i]].plugin;
              name = plugin.getName();
              if (plugin.load && typeof(plugin.load) == "function") plugin.load();
          } catch (err) {
              pluginCookie[name] = false;
              Utils.err("Plugins", name + " could not be loaded.", err);
              bdpluginErrors.push({name: name, file: bdplugins[plugins[i]].filename, message: "load() could not be fired.", error: {message: err.message, stack: err.stack}});
              continue;
          }
  
          if (!pluginCookie[name]) pluginCookie[name] = false;
  
          if (pluginCookie[name]) {
              try {
                  plugin.start();
                  if (settingsCookie["fork-ps-2"]) Utils.showToast(`${plugin.getName()} v${plugin.getVersion()} has started.`);
              } catch (err) {
                  pluginCookie[name] = false;
                  Utils.err("Plugins", name + " could not be started.", err);
                  bdpluginErrors.push({name: name, file: bdplugins[plugins[i]].filename, message: "start() could not be fired.", error: {message: err.message, stack: err.stack}});
              }
          }
  
          await new Promise((resolve) => setTimeout(resolve, 10))
      }
      this.savePluginData();
  
      require("electron").remote.getCurrentWebContents().on("did-navigate-in-page", this.channelSwitch.bind(this));
      // if (settingsCookie["fork-ps-5"]) ContentManager.watchContent("plugin");
  };
  
  PluginModule.prototype.startPlugin = function(plugin, reload = false) {
      try {
          bdplugins[plugin].plugin.start();
          if (settingsCookie["fork-ps-2"] && !reload) Utils.showToast(`${bdplugins[plugin].plugin.getName()} v${bdplugins[plugin].plugin.getVersion()} has started.`);
      }
      catch (err) {
          if (settingsCookie["fork-ps-2"] && !reload) Utils.showToast(`${bdplugins[plugin].plugin.getName()} v${bdplugins[plugin].plugin.getVersion()} could not be started.`, {type: "error"});
          pluginCookie[plugin] = false;
          this.savePluginData();
          Utils.err("Plugins", plugin + " could not be started.", err);
      }
  };
  
  PluginModule.prototype.stopPlugin = function(plugin, reload = false) {
      try {
          bdplugins[plugin].plugin.stop();
          if (settingsCookie["fork-ps-2"] && !reload) Utils.showToast(`${bdplugins[plugin].plugin.getName()} v${bdplugins[plugin].plugin.getVersion()} has stopped.`);
      }
      catch (err) {
          if (settingsCookie["fork-ps-2"] && !reload) Utils.showToast(`${bdplugins[plugin].plugin.getName()} v${bdplugins[plugin].plugin.getVersion()} could not be stopped.`, {type: "error"});
          Utils.err("Plugins", bdplugins[plugin].plugin.getName() + " could not be stopped.", err);
      }
  };
  
  PluginModule.prototype.enablePlugin = function (plugin, reload = false) {
      if (pluginCookie[plugin]) return;
      pluginCookie[plugin] = true;
      this.savePluginData();
      this.startPlugin(plugin, reload);
  };
  
  PluginModule.prototype.enable = function (plugin, reload = false) {
      return this.enablePlugin(plugin, reload);
  };
  
  PluginModule.prototype.disablePlugin = function (plugin, reload = false) {
      if (!pluginCookie[plugin]) return;
      pluginCookie[plugin] = false;
      this.savePluginData();
      this.stopPlugin(plugin, reload);
  };
  
  PluginModule.prototype.disable = function (plugin, reload = false) {
      return this.disablePlugin(plugin, reload);
  };
  
  PluginModule.prototype.togglePlugin = function (plugin) {
      if (pluginCookie[plugin]) this.disablePlugin(plugin);
      else this.enablePlugin(plugin);
  };
  
  PluginModule.prototype.toggle = function (plugin, reload = false) {
      return this.togglePlugin(plugin, reload);
  };
  
  PluginModule.prototype.loadPlugin = async function(filename) {
      const error = await ContentManager.loadContent(filename, "plugin");
      if (error) {
          if (settingsCookie["fork-ps-1"]) Utils.showContentErrors({plugins: [error]});
          if (settingsCookie["fork-ps-2"]) Utils.showToast(`${filename} could not be loaded.`, {type: "error"});
          return Utils.err("ContentManager", `${filename} could not be loaded.`, error);
      }
      const plugin = Object.values(bdplugins).find(p => (console.log(p.filename, filename)) || p.filename == filename).plugin;
      try { if (plugin.load && typeof(plugin.load) == "function") plugin.load();}
      catch (err) {if (settingsCookie["fork-ps-1"]) Utils.showContentErrors({plugins: [err]});}
      Utils.log("ContentManager", `${plugin.getName()} v${plugin.getVersion()} was loaded.`);
      if (settingsCookie["fork-ps-2"]) Utils.showToast(`${plugin.getName()} v${plugin.getVersion()} was loaded.`, {type: "success"});
      BDEvents.dispatch("plugin-loaded", plugin.getName());
  };
  
  PluginModule.prototype.unloadPlugin = function(filenameOrName) {
      const bdplugin = Object.values(bdplugins).find(p => p.filename == filenameOrName) || bdplugins[filenameOrName];
      if (!bdplugin) return;
      const plugin = bdplugin.plugin.getName();
      if (pluginCookie[plugin]) this.disablePlugin(plugin, true);
      const error = ContentManager.unloadContent(bdplugins[plugin].filename, "plugin");
      delete bdplugins[plugin];
      if (error) {
          if (settingsCookie["fork-ps-1"]) Utils.showContentErrors({plugins: [error]});
          if (settingsCookie["fork-ps-2"]) Utils.showToast(`${plugin} could not be unloaded. It may have not been loaded yet.`, {type: "error"});
          return Utils.err("ContentManager", `${plugin} could not be unloaded. It may have not been loaded yet.`, error);
      }
      Utils.log("ContentManager", `${plugin} was unloaded.`);
      if (settingsCookie["fork-ps-2"]) Utils.showToast(`${plugin} was unloaded.`, {type: "success"});
      BDEvents.dispatch("plugin-unloaded", plugin);
  };
  
  PluginModule.prototype.delete = function(filenameOrName) {
      const bdplugin = Object.values(bdplugins).find(p => p.filename == filenameOrName) || bdplugins[filenameOrName];
      if (!bdplugin) return;
      this.unloadPlugin(bdplugin.filename);
      const fullPath = require("path").resolve(ContentManager.pluginsFolder, bdplugin.filename);
      require("fs").unlinkSync(fullPath);
  };
  
  PluginModule.prototype.reloadPlugin = async function(filenameOrName) {
      const bdplugin = Object.values(bdplugins).find(p => p.filename == filenameOrName) || bdplugins[filenameOrName];
      if (!bdplugin) return this.loadPlugin(filenameOrName);
      const plugin = bdplugin.plugin.getName();
      const enabled = pluginCookie[plugin];
      if (enabled) this.stopPlugin(plugin, true);
      const error = await ContentManager.reloadContent(bdplugins[plugin].filename, "plugin");
      if (error) {
          if (settingsCookie["fork-ps-1"]) Utils.showContentErrors({plugins: [error]});
          if (settingsCookie["fork-ps-2"]) Utils.showToast(`${plugin} could not be reloaded.`, {type: "error"});
          return Utils.err("ContentManager", `${plugin} could not be reloaded.`, error);
      }
      if (bdplugins[plugin].plugin.load && typeof(bdplugins[plugin].plugin.load) == "function") bdplugins[plugin].plugin.load();
      if (enabled) this.startPlugin(plugin, true);
      Utils.log("ContentManager", `${plugin} v${bdplugins[plugin].plugin.getVersion()} was reloaded.`);
      if (settingsCookie["fork-ps-2"]) Utils.showToast(`${plugin} v${bdplugins[plugin].plugin.getVersion()} was reloaded.`, {type: "success"});
      BDEvents.dispatch("plugin-reloaded", plugin);
  };
  
  PluginModule.prototype.reload = function(name) {
      return this.reloadPlugin(name);
  };
  
  PluginModule.prototype.edit = function(filenameOrName) {
      const bdplugin = Object.values(bdplugins).find(p => p.filename == filenameOrName) || bdplugins[filenameOrName];
      if (!bdplugin) return;
      const fullPath = require("path").resolve(ContentManager.pluginsFolder, bdplugin.filename);
      require("electron").shell.openExternal(`${fullPath}`);
  };
  
  PluginModule.prototype.updatePluginList = function() {
      const results = ContentManager.loadNewContent("plugin");
      for (const filename of results.added) this.loadPlugin(filename);
      for (const name of results.removed) this.unloadPlugin(name);
  };
  
  PluginModule.prototype.loadPluginData = function () {
      const saved = DataStore.getSettingGroup("plugins");
      if (saved) {
          Object.assign(pluginCookie, saved);
      }
  };
  
  PluginModule.prototype.savePluginData = function () {
      DataStore.setSettingGroup("plugins", pluginCookie);
  };
  
  PluginModule.prototype.newMessage = function () {
      const plugins = Object.keys(bdplugins);
      for (let i = 0; i < plugins.length; i++) {
          const plugin = bdplugins[plugins[i]].plugin;
          if (!pluginCookie[plugin.getName()]) continue;
          if (typeof plugin.onMessage === "function") {
              try { plugin.onMessage(); }
              catch (err) { Utils.err("Plugins", "Unable to fire onMessage for " + plugin.getName() + ".", err); }
          }
      }
  };
  
  PluginModule.prototype.channelSwitch = function () {
      const plugins = Object.keys(bdplugins);
      for (let i = 0; i < plugins.length; i++) {
          const plugin = bdplugins[plugins[i]].plugin;
          if (!pluginCookie[plugin.getName()]) continue;
          if (typeof plugin.onSwitch === "function") {
              try { plugin.onSwitch(); }
              catch (err) { Utils.err("Plugins", "Unable to fire onSwitch for " + plugin.getName() + ".", err); }
          }
      }
  };
  
  PluginModule.prototype.rawObserver = function(e) {
      const plugins = Object.keys(bdplugins);
      for (let i = 0; i < plugins.length; i++) {
          const plugin = bdplugins[plugins[i]].plugin;
          if (!pluginCookie[plugin.getName()]) continue;
          if (typeof plugin.observer === "function") {
              try { plugin.observer(e); }
              catch (err) { Utils.err("Plugins", "Unable to fire observer for " + plugin.getName() + ".", err); }
          }
      }
  };
  
  export default new PluginModule();