// This content script acts as a relay to send messages to and from the
// background script.  Webpage scripts can call `window.postMessage` to send a
// message to the content script which will be caught by this handler, which
// will then forward that message to the background script using inter-script
// message passing.
//
// When the content script receives a response from the background script, it
// will use the same `window.postMessage` api to send that message back to the
// client page (which should also have a message event listener that filters
// for events with the property `event.data.responseFromExtension == true`). 
//
// To ensure that the content script doesn't send its own message (intended for
// the webpage script) to the background script, it creates an envelope with
// two fields: `responseFromExtension` and `response`.  `responseFromExtension`
// will be set to true, indicating that this shouldn't be forwarded to the
// background script. The `response` field will contain whatever data the
// background script sent in response to the initial message.
window.addEventListener("message", async function(event) {
  log("CONTENT MSG EVENT")
  log(event.data)
  var d = event.data;
  if (event.source == window && d) { // Ignore events with no data field and coming from other sources
    if (d._sourceIsExtension) { // If the message we just received came from the extension, don't relay
    } else { // If the message didn't come from the extension, relay it to the background script
      if (d.target == "lode") {  // MESSAGE SEND BY DAPP
        log("CONTENT SEND MSG")
        if (!checkIsPublic(d.data)) {
          const isEnabled = await (
            new Promise((res) => {
              chrome.runtime.sendMessage(["LodePublic_IsEnabled", "stub"], (response) => res(response.response))
            })
          );
          if (!isEnabled) {
            const error = { code: -3, info: "Site not enabled." };
            window.postMessage({_sourceIsExtension: true, id: d.id, response: undefined, error: error }, "*");
            return;
          }
        }
        chrome.runtime.sendMessage(d.data, function(response) {
          log("CONTENT RESPONSE")
          log(response)
          window.postMessage({_sourceIsExtension: true, id: d.id, response: response ? response.response : undefined, error: response ? (response.error ? response.error.external : undefined) : undefined }, "*");
        });
      }
    }
  }
})

const PUBLIC_API = new Set(["LodePublic_Enable", "LodePublic_IsEnabled", "LodePublic_GetWalletIdentity"])
const checkIsPublic = (request) => {
  if (Array.isArray(request) && request.length == 2) {
    return PUBLIC_API.has(request[0]);
  }
  return false;
};

const VERBOSE = false;
const log = (msg) => VERBOSE && console.log(msg);

const injectScript = () => {
  const script = document.createElement('script');
  script.async = false;
  script.src = chrome.runtime.getURL('injected.js');
  script.onload = function () {
    this.remove();
  };
  (document.head || document.documentElement).appendChild(script);
};

function shouldInject() {
  const documentElement = document.documentElement.nodeName;
  const docElemCheck = documentElement
    ? documentElement.toLowerCase() === 'html'
    : true;
  const { docType } = window.document;
  const docTypeCheck = docType ? docType.name === 'html' : true;
  return docElemCheck && docTypeCheck;
}

if (shouldInject()) {
  injectScript();
}

// TODO clean-up this mess ; quick means to tell the tab to reset its wallet endpoint
chrome.runtime.onMessage.addListener(request => {
  window.postMessage({_sourceIsExtension: true, id: null, prompt: "LodePrompt_CheckWalletIdentity"}, "*");
  return;
});

