/*
 * Documentation:
 * https://github.com/thundernest/addon-developer-support/wiki/Using-the-WindowListener-API-to-convert-a-Legacy-Overlay-WebExtension-into-a-MailExtension-for-Thunderbird-78
 */

//TODO
/*
x   note does not close
displaying a new note by click triggers unload listener (ca. 6 times)

upgrade, new pref
*/

'use strict';

const debug = false;//"@@@DEBUGFLAG@@@";

var lastTab = 0, lastWindow = 0;
var openMsgs = [];

var preferenceCache;

var donTimer;

var xnoteKeys = [];

var xnote = {};
xnote.text = "";
xnote.date = "";
xnote.inMsgDisplay = false;
xnote.window = null;
xnote.currentDisplayedMessage = -1;

var xnoteSyncTest = {};



// This is the current "migration" version for preferences. You can increase it later
// if you happen to need to do more pref (or maybe other migrations) only once
// for a user.
const kCurrentLegacyMigration = 5;

// This is the list of defaults for the legacy preferences.
const kPrefDefaults = {
  usetag: true,
  dateformat: "yyyy-mm-dd - HH:MM",
  width: 250,
  height: 200,
  horPos: 250,
  vertPos: 250,
  show_on_select: true,
  show_in_messageDisplay: true,
  show_first_x_chars_in_col: 20,
  storage_path: "[ProfD]XNote",
  show_full_in_messageDisplay: false,
  fetched_old_XNotes: false,
  show_column: true,
};

async function waitForExperiment() {
  let res = false;

  for (let i = 0; i < 500; i++) {
    try {
      res = await messenger.xnoteapi.isExperimentReady();
    }

    catch (ev) { };
    //  console.log("notif exp", i, res);
    if (res) break;
    await wait(100);
  };
};

async function migratePrefs() {
  //console.debug("migratePrefs called.")
  const results = await browser.storage.local.get("preferences");

  const currentMigration =
    results.preferences && results.preferences.migratedLegacy ?
      results.preferences.migratedLegacy : 0;

  if (currentMigration >= kCurrentLegacyMigration) {
    return;
  }

  let prefs = results.preferences || {};

  if (currentMigration < 1) {
    for (const prefName of Object.getOwnPropertyNames(kPrefDefaults)) {
      let oldPrefName = prefName;
      switch (prefName) {
        case "horPos": {
          oldPrefName = "HorPos";
          break;
        }
        case "vertPos": {
          oldPrefName = "VertPos";
          break;
        }
      }
      prefs[prefName] = await browser.xnoteapi.getPref(oldPrefName);
      if (prefs[prefName] === undefined) {
        prefs[prefName] = kPrefDefaults[prefName];
      }
    }
  }

  if (currentMigration < 2) {
    prefs["show_in_messageDisplay"] = kPrefDefaults["show_in_messageDisplay"];
    setTbPref("extensions.xnote.show_in_messageDisplay", kPrefDefaults["show_in_messageDisplay"]);
  }

  if (currentMigration < 3) {
    prefs["show_full_in_messageDisplay"] = kPrefDefaults["show_full_in_messageDisplay"];
    setTbPref("extensions.xnote.show_full_in_messageDisplay", kPrefDefaults["show_full_in_messageDisplay"]);
  }

  if (currentMigration < 4) {
    //this should logically be done here, but it must wait for main() to set prefs in the xnoteapi
    //  await getOldXNotes();
    prefs["fetched_old_XNotes"] = kPrefDefaults["fetched_old_XNotes"];
    setTbPref("extensions.xnote.fetched_old_XNotes", kPrefDefaults["fetched_old_XNotes"]);
  }

  if (currentMigration < 5) {
    //this should logically be done here, but it must wait for main() to set prefs in the xnoteapi
    //  await getOldXNotes();
    prefs["show_column"] = kPrefDefaults["show_column"];
    setTbPref("extensions.xnote.show_column", kPrefDefaults["show_column"]);
  }

  prefs.migratedLegacy = kCurrentLegacyMigration;
  console.debug("Storing migrated preferences.");
  await browser.storage.local.set({ "preferences": prefs });
}

async function getTbPref(name) {
  return browser.xnoteapi.getTbPref(name);
}

async function setTbPref(name, value) {
  browser.xnoteapi.setTbPref(name, value);
}

function getPreferences() {
  // Why would you want to work with the cached values?
  return preferenceCache;
}

async function setPreferences(preferences) {
  let oldShow_column = preferenceCache.show_column;
  //  console.log("col", oldShow_column , preferences.show_column);
  preferenceCache = preferences;
  browser.storage.local.set({ preferences });
  browser.xnoteapi.setPreferences(preferences);
  //  if (oldShow_column != preferences.show_column)
  if (preferences.show_column) {
    await browser.customColumn.add("XNote");

  } else {
    await browser.customColumn.remove("XNote");

  };
}

async function selectDirectory(startDir, title) {
  let result = await browser.xnotefiles.selectDirectory(null, startDir, title);
  //console.debug("select directory returns: " + result);
  return result;
}

async function getProfileDirectory() {
  return await browser.xnotefiles.getProfileDirectory();
}

async function appendRelativePath(basePath, extension) {
  return await browser.xnotefiles.appendRelativePath(basePath, extension);
}

async function wait(t) {
  //	let t = 5000;
  await new Promise(resolve => window.setTimeout(resolve, t));
}

// landing windows.
messenger.runtime.onInstalled.addListener(async ({ reason, temporary }) => {
  // if (temporary) return; // skip during development
  //  console.log("install reason:", reason);
  // setTimeout( () => { let url = messenger.runtime.getURL("/popup/xnotePopUp/xnote-window.html"); messenger.windows.create({ url:url, type:"panel", width: 210 });}, 200);
  setTimeout(() => { let url = messenger.runtime.getURL("/popup/donations.html"); messenger.windows.create({ url: url, type: "popup" }); }, 1000);
  donTimer = setInterval(() => { let url = messenger.runtime.getURL("popup/donations1.html"); messenger.windows.create({ url: url, type: "popup" }); }, 3 * 24 * 60 * 60 * 1000);

  switch (reason) {
    case "install":
      {
        let url = browser.runtime.getURL("popup/installed.html");
        //await browser.tabs.create({ url });
        await messenger.tabs.create({ url });
        //       let wID1 = await browser.windows.create({ url, type: "popup", width: 910, height: 750, });
        //       console.log ("wid", wID1);   

        let answ;
        try {
          answ = await messenger.runtime.sendMessage("expressionsearch@opto.one", { command: "setXNoteInstalled" });
        }
        catch (e) {
          //          let url = messenger.runtime.getURL("popup/ExprSearch.html"); messenger.windows.create({ url: url, type: "popup" });
          //      console.log("ans exp", answ);
        };

      };
      break;
    // see below
    case "update":
      {
        let url = browser.runtime.getURL("popup/update.html");
        //        let url2 = browser.runtime.getURL("popup/installed.html");
        await browser.tabs.create({ url });
        //   let wID = await browser.windows.create({ url, type: "popup", width: 910, height: 750, });
        //        console.log ("wid", wID);
        //       debugger;
        //        let tID = await messenger.tabs.create({active:true, index:1, url: "http://www.google.com", windowId: wID.id});
        ////   let tID = await messenger.tabs.create({windowId: wID.id});
        //    tID = await messenger.tabs.create({windowId: wID.id});
        //     tID = await messenger.tabs.create({windowId: wID.id});
        //      console.log ("tid", tID);   
      }
      break;
    // see below
  }
});



async function removeNoteOnFolderChange(tab, displayedFolder) {
  let actMailTab = await messenger.mailTabs.getCurrent();
  if (actMailTab && (tab.id == actMailTab.id)) {
    //    console.log("Folchange", tab, displayedFolder);
    messenger.xnoteapi.closeNoteWindow(tab.windowId);
    xnote.text = "";
  };

};


async function updateXNoteTag(msgId, removeTag) {
  let msg1 = await messenger.messages.get(msgId);
  let tags = msg1.tags;
  //       console.log("tags", tags, msg1);// msgs);
  let hasXNoteTag = false;
  if (tags.length) hasXNoteTag = tags.toString().includes("xnote");
  if (!removeTag && !hasXNoteTag) {
    tags.push("xnote");
    await messenger.messages.update(msgId, { tags: tags });  //

  };

  if (removeTag) {
    let index = tags.indexOf("xnote");
    if (index > -1) tags.splice(index, 1);
    if (tags.length == 0) tags.push("");
    await messenger.messages.update(msgId, { tags: tags });  //
  };

};

messenger.NotifyTools.onNotifyBackground.addListener(async (info) => {
  switch (info.command) {



    case "closeNote":
      let actMailTab = await messenger.mailTabs.getCurrent();
      if (true) {
        //    console.log("Folchange", tab, displayedFolder);
        messenger.xnoteapi.closeNoteWindow(actMailTab.windowId);
        xnote.text = "";
      };
      break;
    case "searchXNotes":
      //    console.log("xn bgr searh");
      let answ;
      try {
        answ = await messenger.runtime.sendMessage("expressionsearch@opto.one", { command: "searchXNotes" });
        messenger.xnoteapi.closeNoteWindow(activeInfo.windowId);

      }
      catch (e) {
        let url = messenger.runtime.getURL("popup/ExprSearch.html"); messenger.windows.create({ url: url, type: "popup" });
        //      console.log("ans exp", answ);
      };
      break;
    case "setBookmark":
      messenger.runtime.sendMessage("bookmarks@opto.one", { content: "addXnoteBookmark" }, {});
      break;
    case "saveXNote":
      let cc = { [info.hdrMsgId]: info.XNote };
      //    console.log("toDB", cc);
      if (!xnoteKeys.includes(info.hdrMsgId)) xnoteKeys.push(info.hdrMsgId);

      let msg = { command: "saveXnote", hdrMsgId: info.hdrMsgId, note: info.XNote, xnoteKeys: xnoteKeys };
      await messenger.storage.local.set(cc);
      if (!xnoteKeys.includes(info.hdrMsgId)) xnoteKeys.push(info.hdrMsgId);
      await messenger.storage.local.set({ "keys": xnoteKeys });
      /*
      //coming later
     */
      try {
        let resp = await browser.runtime.sendMessage(
          "expressionsearch@opto.one",
          msg
        );
      } catch (ev) { };
      if (info.sync) {
        //only sync if created locally, not if just received by sync
        msg.command = "syncXNote";
        //     console.log("msg", msg);
        try {
          let resp = await browser.runtime.sendMessage(
            "sync@opto.one",
            msg
          );
        } catch (ev) {
          //console.log("sync not installed", ev); 
        };
      };
      break;

    case "deleteXNote":
      //console.log("delDB", info.hdrMsgId);
      await messenger.storage.local.remove(info.hdrMsgId.toString());
      xnoteKeys = xnoteKeys.filter(item => item !== info.hdrMsgId.toString());
      await messenger.storage.local.set({ "keys": xnoteKeys });
      xnote.text = "";
      //    xnote.date = xnote1.date;
      await messenger.storage.local.set({ "xnote": xnote }); //to forward to messagedisplayscript

      let msgD = { command: "deleteXnote", xnoteKeys: xnoteKeys, hdrMsgId: info.hdrMsgId };
      try {
        let respD = await browser.runtime.sendMessage(
          "expressionsearch@opto.one",
          msgD
        );
      } catch (ev) { };


      /*115
           let msgD = { command: "deleteXnote", xnoteKeys: xnoteKeys, hdrMsgId: info.hdrMsgId };
           let respD = await browser.runtime.sendMessage(
             "expressionsearch@opto.one",
             msgD
           );
     */
      if (info.sync) {
        //only sync if deleted locally, not if just received by sync

        try {
          let resp = await browser.runtime.sendMessage(
            "sync@opto.one",
            msgD
          );
        } catch (ev) { console.log("syncdel", ev); };
      };
      break;

    case "getXNote":
      let note = await messenger.storage.local.get(info.hdrMsgId);
      //          console.log("note", note);
      break;

    case "getCommandKey":
      let commands = await messenger.commands.getAll();//.local.get(info.hdrMsgId);
      //   console.log("comm", commands[0]);
      //          console.log("note", note);
      // let comm1 = commands.filter(  (comm) => {   (comm.name != "openXNoteWindow")   });
      return commands[0];
      break;
      break;

    case "updateTag":
      //       console.log("updateTag", info);
      //      let mailTabsArr = await messenger.mailTabs.query({active:true, lastFocusedWindow:true});  //active:true,
      //      console.log("mailtabs", mailTabsArr);
      //let msg1 = await browser.messageDisplay.getDisplayedMessage(tab.id)

      let msg1 = await messenger.messages.get(info.info.msgId);
      //   let msgs = [msg];//await messenger.mailTabs.getSelectedMessages(mailTabsArr[0].id);
      //   console.log("tags",  msgs, msgs.messages[0]);
      let tags = msg1.tags;//msgs.messages[0].tags;
      //       console.log("tags", tags, msg1);// msgs);
      let hasXNoteTag = false;
      if (tags.length) hasXNoteTag = tags.toString().includes("xnote");
      if (info.info.addTag && !hasXNoteTag) {
        tags.push("xnote");
        //      messenger.messages.update(msgs.messages[0].id,{tags: tags});
        //    console.log("tags", tags,  tags.toString(), hasXNoteTag);

        messenger.messages.update(info.info.msgId, { tags: tags });  //
        //        messenger.messages.update(msg1.id, { tags: tags });  //

      } else {
        if (info.info.removeTag) {  //&&hasXNoteTag
          let index = tags.indexOf("xnote");
          if (index > -1) tags.splice(index, 1);
          if (tags.length == 0) tags.push("");
          messenger.messages.update(info.info.msgId, { tags: tags });  //
          //          messenger.messages.update(msg1.id, { tags: tags });  //
        };

      };
      //  let message = await browser.messageDisplay.getDisplayedMessage(tab.id);
      //     let commands1 = await messenger.commands.getAll();//.local.get(info.hdrMsgId);
      //   console.log("comm", commands[0]);
      //          console.log("note", note);
      // let comm1 = commands.filter(  (comm) => {   (comm.name != "openXNoteWindow")   });
      return;
  }



});

async function addToDB(msgKey) {
  let note = await browser.xnoteapi.getXNoteFromMsgKey(msgKey);
  if (!note) return;
  let cc = { [msgKey]: note };
  //console.log("note", cc);
  await messenger.storage.local.set(cc);
  if (!xnoteKeys.includes(msgKey)) {
    xnoteKeys.push(msgKey);
    await messenger.storage.local.set({ "keys": xnoteKeys });
  };

};

async function getOldXNotesOneByOne() {
  //this should logically be done in migraterefs, but it must wait for main() to set prefs in the xnoteapi

  await new Promise(resolve => setTimeout(resolve, 1000));
  //  let notesk = await browser.xnoteapi.getAllXNotesFromDirectory();
  // debugger;
  let notesk = await browser.xnoteapi.getAllXNoteKeys();
  // console.log("fetch old xnotes", notesk.keys.length, notesk.keys, typeof notesk.keys, Array.isArray(notesk.keys));
  for (let i = 0; i < notesk.keys.length; i++)  addToDB(notesk.keys[i]);
  /**/

  //set pref
  preferenceCache["fetched_old_XNotes"] = true;
  let prefs = preferenceCache;
  setPreferences(prefs);

};



async function getOldXNotes() {
  //this should logically be done in migraterefs, but it must wait for main() to set prefs in the xnoteapi

  await new Promise(resolve => setTimeout(resolve, 1000));
  let notesk = await browser.xnoteapi.getAllXNotesFromDirectory();
  //  console.log("fetch old xnotes", notesk);
  /**/
  notesk.all.forEach(async element => {

    let cc = { [element[0]]: element[1] };
    await messenger.storage.local.set(cc);
    if (!xnoteKeys.includes(element[0])) {
      xnoteKeys.push(element[0]);
      await messenger.storage.local.set({ "keys": xnoteKeys });
    };
  });
  //set pref
  preferenceCache["fetched_old_XNotes"] = true;
  let prefs = preferenceCache;
  setPreferences(prefs);

};


function handleMessage(request, sender, sendResponse) {
  sendResponse({ response: "Response from background script" });
  //console.log(`A content script sent a message: ${request.command}`);
  if (request.command == "stopDonPopup") clearInterval(donTimer);
}

browser.runtime.onMessage.addListener(handleMessage);

// This is the final onActivated function, which is called 
// * on the active tab after load
// * on tabs, which have been created as active
// * on each standard tab switch
async function onSafeActivated(activeInfo) {
  //console.log("onSafeActivated");
  await new Promise(resolve => setTimeout(resolve, 1000));
  let tab = await messenger.tabs.get(activeInfo.tabId);
  //  console.log(`Tab ${tab.id} in window ${tab.windowId} was activated (mailtab: ${tab.mailTab}).`);
  //  messenger.Utilities.isMailTab(tab.mailTab || tab.type == "messageDisplay", tab.type == "messageDisplay");
}

// Wait until we have at least one window with an active tab.
async function waitForWindow() {
  let windows = await browser.windows.getAll({ windowTypes: ["normal"] });
  for (let win of windows) {
    let activeTabs = await messenger.tabs.query({ active: true, windowId: win.id });
    if (activeTabs.length == 1) {
      onSafeActivated({ tabId: activeTabs[0].id, windowId: activeTabs[0].windowId });
    } else {
      console.error(`Did not find exactly one active tab in window ${win.id}:`, activeTabs);
    }
  }
}



//var portFromBookmarks = null;
async function main() {
  //  await wait(1000);  //to allow rsourceurl to be created

  // Register the chrome url, so any code running after this can access them.
  await messenger.WindowListener.registerChromeUrl([
    ["content", "xnote", "chrome/content/"],
    ["resource", "xnote", "chrome/"],

    ["locale", "xnote", "en-US", "chrome/locale/en-US/"],
    ["locale", "xnote", "de", "chrome/locale/de/"],
    ["locale", "xnote", "fr-FR", "chrome/locale/fr-FR/"],
    ["locale", "xnote", "gl", "chrome/locale/gl/"],
    ["locale", "xnote", "it-IT", "chrome/locale/it-IT/"],
    ["locale", "xnote", "ja-JP", "chrome/locale/ja-JP/"],
    ["locale", "xnote", "nl-NL", "chrome/locale/nl-NL/"],
    ["locale", "xnote", "pl-PL", "chrome/locale/pl-PL/"],
    ["locale", "xnote", "pt-BR", "chrome/locale/pt-BR/"],
  ]);

  await waitForExperiment();
  await waitForWindow();

  await new Promise(resolve => setTimeout(resolve, 1000));
  //console.log("before WL in main");



  preferenceCache = (await browser.storage.local.get("preferences")).preferences;
  await browser.xnoteapi.loadXNoteJSM();
  await migratePrefs();
  preferenceCache = (await browser.storage.local.get("preferences")).preferences;
  //  console.log("bgr-prefs", preferenceCache);
  await browser.xnoteapi.setPreferences(preferenceCache);
  await browser.xnoteapi.init();


  messenger.WindowListener.registerWindow(
    "chrome://messenger/content/messenger.xhtml",
    //   "about:3pane",  
    "chrome/content/scripts/xn-xnote-overlay.js"
  );

  messenger.WindowListener.registerWindow(
    //  "chrome://messenger/content/messenger.xhtml",
    "about:3pane",
    "chrome/content/scripts/xn-xnote-aboutOverlay.js"
  );

  await messenger.WindowListener.startListening();

  //  await migratePrefs();


  //if (preferenceCache["fetched_old_XNotes"] == false) getOldXNotes();
  getOldXNotesOneByOne();


  messenger.tabs.onActivated.addListener(async (activeInfo) => {
    let lastTabId = activeInfo.previousTabId;
    // console.log("tab actic, last, new", activeInfo.previousTabId, activeInfo.tabId); //102tabId;
    lastWindow = activeInfo.windowId;
    let tabInfo = await messenger.tabs.get(activeInfo.tabId);
    if (!tabInfo.mailTab) {
      if (lastTabId) {
        tabInfo = await messenger.tabs.get(lastTabId);
        //    console.log("tabaciv, close xnote", tabInfo);
        messenger.xnoteapi.closeNoteWindow(tabInfo.windowId);
        //102     messenger.xnoteapi.closeNoteWindow(activeInfo.windowId);
        xnote.text = "";
      };
      return;
    }
    else {
      try {
        let xnote_displayed = await messenger.xnoteapi.hasOpenNoteWindow(activeInfo.windowId);
        if (!xnote_displayed) {

          let message = await browser.messageDisplay.getDisplayedMessage(activeInfo.tabId)
          let xnote1 = await messenger.xnoteapi.getXNote(message.id);
          if (xnote1.text != "") await messenger.xnoteapi.openNoteWindow(activeInfo.windowId, message.id, true, true);
        }
      }
      catch (e) { };
    };

    if (tabInfo.type != "mail") {
      messenger.xnoteapi.closeNoteWindow(activeInfo.windowId);
      xnote.text = "";
    };

  });


  messenger.tabs.onCreated.addListener((tab) => {
    //    console.log("created tabname", tab.title);
    if (!tab.mailTab) {
      messenger.xnoteapi.closeNoteWindow(tab.windowId);
      xnote.text = "";
    };
  });


  messenger.mailTabs.onDisplayedFolderChanged.addListener(removeNoteOnFolderChange);
  messenger.mailTabs.onSelectedMessagesChanged.addListener(removeNoteOnFolderChange);

  browser.browserAction.onClicked.addListener(async (tab, info) => {


    if (info.modifiers.includes("Shift")) {
      // console.log("Shift");
      let message = await browser.messageDisplay.getDisplayedMessage(tab.id)
      let xnote1 = await messenger.xnoteapi.getXNote(message.id);

      xnoteSyncTest = await messenger.xnoteapi.getXNoteFromMsgKey(message.headerMessageId);
      //      console.log("XNote", xnote1, xnoteSyncTest, message, xnoteSyncTest.note);
      let actTab = await messenger.mailTabs.getCurrent();
      let selFolders = await messenger.mailTabs.getSelectedFolders(actTab.id);
      if (selFolders.length);
      //        messenger.ExpressionSearchTools.openSearchInTab(selFolders[0].accountId, selFolders[0].path);   // use first selected folder
    } else {
      if (info.modifiers.includes("Alt")) {
        // console.log("Shift");
        //       let message = await browser.messageDisplay.getDisplayedMessage(tab.id)
        //        let xnote1 = await messenger.xnoteapi.getXNote(message.id);
        //        console.log("XNote", xnote1);
        let actTab = await messenger.mailTabs.getCurrent();
        let selFolders = await messenger.mailTabs.getSelectedFolders(actTab.id);
        if (selFolders.length) {
          let msgList = await messenger.messages.list(selFolders[0].id);
          let jsn = JSON.stringify(xnoteSyncTest.note);
          //         console.log("JSON", xnoteSyncTest.note, jsn);
          let cleanNote = JSON.parse(jsn);
          //          console.log("JSON", xnoteSyncTest.note, jsn, cleanNote);

          // Do something with msgList.messages.
          for (let message of msgList.messages) {
            //        let cleanNote = JSON.parse(JSON.stringify( xnoteSyncTest.note));
            await messenger.xnoteapi.syncXNote(message.headerMessageId, cleanNote);

          }

          while (msgList.id) {
            msgList = await messenger.messages.continueList(msgList.id);
            // Do something with page.messages.
            for (let message of msgList.messages) {
              await messenger.xnoteapi.syncXNote(message.headerMessageId, xnoteSyncTest);

            }
          };
          //         console.log("copy notes finished");
          let show_column = getTbPref("show_column");
          if (show_column) {
            await browser.customColumn.refreshColumn("XNote");

          };
          let mt = await messenger.mailTabs.getCurrent();
          //not updating view:         await messenger.mailTabs.update({displayedFolder: mt.displayedFolder});
        };
        //        messenger.ExpressionSearchTools.openSearchInTab(selFolders[0].accountId, selFolders[0].path);   // use first selected folder
      } else {      //   messenger.xnoteapi.getAllXNoteKeys();
        let xnote_displayed = await messenger.xnoteapi.hasOpenNoteWindow(tab.windowId);
        if (!xnote_displayed) {
          //         let message = await browser.messageDisplay.getDisplayedMessage(tab.id);
          //          console.log("messDispl1", tab);
          if (tab.mailTab) {
            let msgs = (await browser.mailTabs.getSelectedMessages(tab.id));
            let message = msgs.messages[0];
            //            console.log("messDispl", tab, message, msgs);
            if (msgs.messages.length == 1) await messenger.xnoteapi.openNoteWindow(tab.windowId, message.id, true, true);
            else messenger.notifications.create({ title: "Attention", message: "Cannot create XNote if multiple messages are selected", type: "basic" });
          } else {
            if (tab.type == "messageDisplay") {
              let msgs = await browser.messageDisplay.getDisplayedMessages(tab.id);
              if (msgs.length == 1) {
                let msg = msgs[0];
                let xnote1 = await messenger.xnoteapi.getXNote(msg.id);
                //                console.log("messD", xnote1, msg);
                if (xnote1.text == "") {
                  //                  console.log("new note");
                  await messenger.xnoteapi.openNoteWindow(tab.windowId, msg.id, true, true);

                } else {
                  await messenger.xnoteapi.openNoteWindow(tab.windowId, msg.id, true, true);

                };
              } else {
                messenger.notifications.create({ title: "Attention", message: "Cannot create XNote if multiple messages are selected", type: "basic" });

              };
            };
          };
        } else {
          messenger.xnoteapi.closeNoteWindow(tab.windowId);
        }
      }
    }
  });




  messenger.messageDisplay.onMessageDisplayed.addListener(async (tab, message) => {
    xnote.currentDisplayedMessage = message.id;
    //debugger;
    let xnote1 = await messenger.xnoteapi.getXNote(message.id);
    xnote.text = xnote1.text;
    xnote.date = xnote1.date;
    if (preferenceCache["show_in_messageDisplay"] == false) xnote.text = "";
    await messenger.storage.local.set({ "xnote": xnote });

    //    if (preferenceCache["show_in_messageDisplay"] == false) xnote1.text = "";
    //    xnote1.show_full_in_messageDisplay = preferenceCache["show_full_in_messageDisplay"];
    //    xnote.text = xnote1.text;
    //    xnote.date = xnote1.date;
    //    await messenger.storage.local.set({ "xnote": xnote });
    //    console.log("onMessageDisplayed", xnote1);
    await messenger.xnoteapi.closeNoteWindow(tab.windowId);
    //bugfix: prefs are stored in legacy in 2 places, so use forceshowing
    if (xnote1.text != "") await messenger.xnoteapi.openNoteWindow(tab.windowId, message.id, preferenceCache["show_on_select"], true);//was show_column
    //  console.log("onMessDispl messid",  message.headerMessageId);
    /*   let note = (await messenger.storage.local.get(message.headerMessageId))[message.headerMessageId];
  //    console.log("note", note);
   if (   xnote.window )  {
  //  console.log("winid", xnote.window);
    messenger.windows.remove(xnote.window.id);
    //   xnote.window.close();
       xnote.window = "null";
   };
  
      let url = messenger.runtime.getURL("/popup/xnotePopUp/xnote-window.html"); 
      if ( Object.keys(note).length > 0  ) xnote.window = await  messenger.windows.create({ url:url, type:"panel", width: 210 });
     // if ( note ) xnote.window = await  messenger.windows.create({ url:url, type:"panel", width: 210 });
   //   console.log("winid", message, xnote.window, message.id, message.headerMessageId, note, Object.keys(note), Object.keys(note).length);
  */

  });





  /**/
  //  console.log("before messageExternal");
  messenger.runtime.onMessageExternal.addListener(async (message, sender, sendResponse) => {
    //   console.log("in messageExternal", message, sender);
    if (sender.id === "expressionsearch@opto.one") {
      if (message.command == "getXnote") {
        //         console.log("hdr", message.hdrID);
        let note = await messenger.storage.local.get(message.hdrID);
        //         console.log("note", note);
        return note;

      };

      if (message.command == "getXnoteDir") {
        //console.log("prefs", getPreferences().storage_path);

        //         console.log("note", note);
        //sendResponse({resp:"test3"});//note);
        return getPreferences().storage_path;

      };


      if (message.command == "getAllXNotes") {
        //       let notes = await messenger.storage.local.get(null);
        let keys = await messenger.storage.local.get("keys");
        //     console.log("keys", keys);
        let all = {};
        // let one = {};
        for (let i = 0; i < keys.keys.length; i++) {
          let key = keys.keys[i];
          let elem = await messenger.storage.local.get(key);
          //         console.log("key", key, "elem", elem);
          //         console.log("elkey", elem[key]);
          all[key] = elem[key];
        };
        //       console.log("all", notes, "onebyone", all );
        return all;

      };



    };

    if (sender.id === "sync@opto.one") {
      if (message.command == "getXnote") {
        //         console.log("hdr", message.hdrID);
        let note = await messenger.storage.local.get(message.hdrID);
        //         console.log("note", note);
        return note;

      };

      if (message.command == "isXnoteReady") {
        //         console.log("hdr", message.hdrID);
        await waitForExperiment();
        //         console.log("note", note);
        return true;

      };


      if (message.command == "getXnoteDir") {
        //console.log("prefs", getPreferences().storage_path);

        //         console.log("note", note);
        //sendResponse({resp:"test3"});//note);
        return getPreferences().storage_path;

      };



      if (message.command == "saveXnoteFromSync") {
        if (!message.deleted) messenger.xnoteapi.syncXNote(message.hdrMsgId, message.note);
        else messenger.xnoteapi.deleteXNoteFromMsgKey(message.hdrMsgId);
        //display or change tag
        let msgs = await messenger.messages.query({ "headerMessageId": message.hdrMsgId });
        if (msgs.messages.length) {
          for (let i = 0; i < msgs.messages.length; i++) {
            updateXNoteTag(msgs.messages[i].id, message.deleted);
          };
        };
        //sendResponse({resp:"test3"});//note);
        //return getPreferences().storage_path;

      };

      if (message.command == "getAllXNotesToSync") {
        //       let notes = await messenger.storage.local.get(null);
        //get it from XNote directory
        let notesk = await browser.xnoteapi.getAllXNotesFromDirectory();

        /*
      //get it from storage,local
        let keys = await messenger.storage.local.get("keys");
        //     console.log("keys", keys);
        let all = [], jsAll = [];
        // let one = {};
        for (let i = 0; i < keys.keys.length; i++) {
          let key = keys.keys[i];
          let elem = await messenger.storage.local.get(key);
          //         console.log("key", key, "elem", elem);
          //         console.log("elkey", elem[key]);
          let               jsNote = [key, elem[key] ];
          jsAll.push(jsNote);
 
          //all[key] = elem[key];
        };
        //       console.log("all", notes, "onebyone", all );
 return jsAll;
        */
        return notesk.all;

      };

      if (message.command == "getAllXNoteKeysToSync") {
        //       let notes = await messenger.storage.local.get(null);
        //get it from XNote directory
        let notesk = await browser.xnoteapi.getAllXNoteKeys();

        /*
      //get it from storage,local
        let keys = await messenger.storage.local.get("keys");
        //     console.log("keys", keys);
        let all = [], jsAll = [];
        // let one = {};
        for (let i = 0; i < keys.keys.length; i++) {
          let key = keys.keys[i];
          let elem = await messenger.storage.local.get(key);
          //         console.log("key", key, "elem", elem);
          //         console.log("elkey", elem[key]);
          let               jsNote = [key, elem[key] ];
          jsAll.push(jsNote);
 
          //all[key] = elem[key];
        };
//               console.log("all", notes, "onebyone", all );
 return jsAll;
        */
        // console.log("allKeys", notesk );
        return notesk;

      };
      //
      if (message.command == "getXNoteFromMsgKey") {
        //       let notes = await messenger.storage.local.get(null);
        //get it from XNote directory
        let note = await browser.xnoteapi.getXNoteFromMsgKey(message.hdrMsgId);

        /*
      //get it from storage,local
        let keys = await messenger.storage.local.get("keys");
        //     console.log("keys", keys);
        let all = [], jsAll = [];
        // let one = {};
        for (let i = 0; i < keys.keys.length; i++) {
          let key = keys.keys[i];
          let elem = await messenger.storage.local.get(key);
          //         console.log("key", key, "elem", elem);
          //         console.log("elkey", elem[key]);
          let               jsNote = [key, elem[key] ];
          jsAll.push(jsNote);
 
          //all[key] = elem[key];
        };
 //              console.log("all", notes, "onebyone", all );
 return jsAll;
        */
        // console.log("noteByKey", note );
        return note;

      };
    };



  });




  /*
   * Show note info in message display
   */

  async function toMessDisplScript(message) {
    if (message.command == "getXNote") {
      //115     let msg = await messenger.messageDisplay.getDisplayedMessage(sender.tab.id);
      let msg = await messenger.messages.get(xnote.currentDisplayedMessage);
      //   console.log("sender", sender,msg);
      let xnote1 = await messenger.xnoteapi.getXNote(msg.id);
      if (preferenceCache["show_in_messageDisplay"] == false) xnote1.text = "";
      xnote1.show_full_in_messageDisplay = preferenceCache["show_full_in_messageDisplay"];
      // sendResponse({ xnote: xnote1 });
      return { xnote: xnote1 };
    };

  };

  var doHandleCommand = async (message, sender) => {
    const { command } = message;
    const {
      tab: { id: tabId },
    } = sender;

    const messageHeader = await browser.messageDisplay.getDisplayedMessage(tabId);

    // console.log("messageHeader", messageHeader);

    // Check for known commands.
    switch (command.toLocaleLowerCase()) {
      case "getnotificationdetails":
        {
          // Create the information chunk we want to return to our message content
          // script.
          //        console.log("getnotificationdetails");
          return {
            text: `Mail subject is "${messageHeader.subject}"`,
          };
        }
        break;

      case "markunread":
        {
          // Get the current message from the given tab.
          if (messageHeader) {
            // Mark the message as unread.
            browser.messages.update(messageHeader.id, {
              read: false,
            });
          }
        }
        break;
    }
  };

  browser.runtime.onMessage.addListener((message, sender, sendResponse) => {
    //   console.log(message, sender, xnote.currentDisplayedMessage);
    //    debugger;
    /*
        if (message.command == "getXNote") {
     //115     let msg = await messenger.messageDisplay.getDisplayedMessage(sender.tab.id);
     let msg = await messenger.messages.get(xnote.currentDisplayedMessage);
  //   console.log("sender", sender,msg);
          let xnote1 = await messenger.xnoteapi.getXNote(msg.id);
          if (preferenceCache["show_in_messageDisplay"] == false) xnote1.text = "";
          xnote1.show_full_in_messageDisplay = preferenceCache["show_full_in_messageDisplay"];
          sendResponse({ xnote: xnote1 });
        //  return xnote1;
        };
    
    let mmm = toMessDisplScript(message);
    //sendResponse({ xnote: "test" });
    //return { xnote: "test" };
    return toMessDisplScript(message);
    //return Promise.resolve({ response: mmm });
    */

    if (message && message.hasOwnProperty("command")) {
      // If we have a command, return a promise from the command handler.

      return doHandleCommand(message, sender);
    }
    return false;


  });

  // Only loads into new messages, so on install, it will not load into the
  // already open message.
  await messenger.messageDisplayScripts.register({
    js: [{ file: "mDisplay.js" }]
    //,
    //css: [{ file: "/src/message-content-styles.css" }],
  });


  messenger.commands.onCommand.addListener(async function (command, tab) {
    //console.log("command", command);
    if (command === "openXNoteWindow") {
      let xnote_displayed = await messenger.xnoteapi.hasOpenNoteWindow(tab.windowId);
      //console.log("commandx", xnote_displayed);
      if (!xnote_displayed) {
        let message = await browser.messageDisplay.getDisplayedMessage(tab.id)
        //       console.log("commandm", message);
        await messenger.xnoteapi.openNoteWindow(tab.windowId, message.id, true, true);
      } else {
        messenger.xnoteapi.closeNoteWindow(tab.windowId);
      }
    };
    if (command === "getOldXNotes") {
      getOldXNotes();
      //    console.log("getOldXNotes");
      /*      let xnote_displayed = await messenger.xnoteapi.hasOpenNoteWindow(tab.windowId);
            //        console.log("commandx", xnote_displayed);
            if (!xnote_displayed) {
              let message = await browser.messageDisplay.getDisplayedMessage(tab.id)
              //       console.log("commandm", message);
              await messenger.xnoteapi.openNoteWindow(tab.windowId, message.id, true, true);
            } else {
              messenger.xnoteapi.closeNoteWindow(tab.windowId);
            } */
    };
  });


  if (preferenceCache.show_column) {
    await browser.customColumn.add("XNote");

  } else {
    await browser.customColumn.remove("XNote");

  };


  /*
  //leaving in, but seems double
    messenger.messageDisplay.onMessageDisplayed.addListener(async (tab, message) => {
      await messenger.xnoteapi.closeNoteWindow(tab.windowId);
      await messenger.xnoteapi.openNoteWindow(tab.windowId, message.id, false);
    });
  */
  /*
   * Start listening for opened windows. Whenever a window is opened, the registered
   * JS file is loaded. To prevent namespace collisions, the files are loaded into
   * an object inside the global window. The name of that object can be specified via
   * the parameter of startListening(). This object also contains an extension member.
   */

  // WE USE THIS ONLY FOR THE MENU ENTRIES - GET RID OF IT - USE MENUS API
  // messenger.WindowListener.registerWindow(
  //115 "chrome://messenger/content/messenger.xhtml",
  // "about:3pane",  "chrome/content/scripts/xn-xnote-overlay.js"
  // );
  // messenger.WindowListener.startListening();
}

main().catch(console.error);
