/* global sendMessage */

"use strict";

var stableRules = null;
var unstableRules = null;

function e(id) {
  return document.getElementById(id);
}

/**
 * Handles rule (de)activation in the popup
 * @param checkbox checkbox being clicked
 * @param ruleset the ruleset tied tot he checkbox
 */
function toggleRuleLine(checkbox, ruleset, tab_id) {
  var ruleset_active = checkbox.checked;
  var set_ruleset = {
    active: ruleset_active,
    name: ruleset.name,
    tab_id: tab_id
  };

  sendMessage("set_ruleset_active_status", set_ruleset, function(){

    if (ruleset_active == ruleset.default_state) {
      // purge the name from the cache so that this unchecking is persistent.
      sendMessage("delete_from_ruleset_cache", ruleset.name);
    }

    // Now reload the selected tab of the current window.
    chrome.tabs.reload();
  });
}

/**
 * Creates a rule line (including checkbox and icon) for the popup
 * @param ruleset the ruleset to build the line for
 * @returns {*}
 */
function appendRuleLineToListDiv(ruleset, list_div, tab_id) {

  // parent block for line
  var line = document.createElement("div");
  line.className = "rule checkbox";

  // label "container"
  var label = document.createElement("label");

  // checkbox
  var checkbox = document.createElement("input");
  checkbox.type = "checkbox";
  checkbox.checked = ruleset.active;
  checkbox.onchange = function() {
    toggleRuleLine(checkbox, ruleset, tab_id);
  };
  label.appendChild(checkbox);

  // label text
  var text = document.createElement("span");
  text.innerText = ruleset.name;
  if (ruleset.note.length) {
    text.title = ruleset.note;
  }

  if(ruleset.note == "user rule") {
    var remove = document.createElement("img");
    remove.src = chrome.extension.getURL("remove.png");
    remove.className = "remove";
    line.appendChild(remove);

    remove.addEventListener("click", function(){
      sendMessage("remove_rule", ruleset);
      list_div.removeChild(line);
    });
  }

  label.appendChild(text);

  line.appendChild(label);

  list_div.appendChild(line);
}

function showHttpNowhereUI() {
  // Set up checkbox for HTTP nowhere mode
  getOption_('httpNowhere', false, function(item) {
    if (item.httpNowhere) {
      e('http-nowhere-checkbox').checked = true;
    }
    show(e('HttpNowhere'));
  });
};

// Change the UI to reflect extension enabled/disabled
function updateEnabledDisabledUI() {
  getOption_('globalEnabled', true, function(item) {
    document.getElementById('onoffswitch').checked = item.globalEnabled;
    show(e('disableButton'));
    // Hide or show the rules sections
    if (item.globalEnabled) {
      document.body.className = ""
      showHttpNowhereUI()
    } else {
      document.body.className = "disabled"
    }
  });
}

// Toggle extension enabled/disabled status
function toggleEnabledDisabled() {
  var extension_toggle_effect = function(){
    updateEnabledDisabledUI();
    // The extension state changed, so reload this tab.
    chrome.tabs.reload();
    window.close();
  }

  getOption_('globalEnabled', true, function(item) {
    setOption_('globalEnabled', !item.globalEnabled, extension_toggle_effect);
  });

}

/**
 * Create the list of rules for a specific tab
 * @param tabArray
 */
function gotTab(activeTab) {
  sendMessage("get_active_rulesets", activeTab.id, function(rulesets){
    for (var r in rulesets) {
      var listDiv = stableRules;
      if (!rulesets[r].default_state) {
        listDiv = unstableRules;
      }
      appendRuleLineToListDiv(rulesets[r], listDiv, activeTab.id);
      listDiv.style.display = 'block';
    }
    // Only show the "Add a rule" link if we're on an HTTPS page
    if (/^https:/.test(activeTab.url)) {
      show(e("add-rule-link"));
    }
  });
}

/**
 * Fill in content into the popup on load
 */
document.addEventListener("DOMContentLoaded", function () {
  stableRules = document.getElementById("StableRules");
  unstableRules = document.getElementById("UnstableRules");
  getTab(gotTab);

  // Set up the enabled/disabled switch & hide/show rules
  updateEnabledDisabledUI();
  document.getElementById('onoffswitch').addEventListener('click', toggleEnabledDisabled);
  e('http-nowhere-checkbox').addEventListener('click', toggleHttpNowhere, false);

  // Print the extension's current version.
  var the_manifest = chrome.runtime.getManifest();
  var version_info = document.getElementById('current-version');
  version_info.innerText = the_manifest.version;

  e("aboutTitle").title = chrome.i18n.getMessage("about_title");
  e("add-rule-link").addEventListener("click", addManualRule);
});


var escapeForRegex = function( value ) {
  return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
};

function hide(elem) {
  elem.style.display = "none";
}

function show(elem) {
  elem.style.display = "block";
}

/**
 * Handles the manual addition of rules
 */
function addManualRule() {
  getTab(function(tab) {
    hide(e("add-rule-link"));
    show(e("add-new-rule-div"));

    const url = new URL(tab.url);

    e("new-rule-host").value = url.host;

    const escapedHost = escapeForRegex(url.host);

    e("new-rule-regex").value = `^http://${escapedHost}/`;
    e("new-rule-redirect").value = `https://${url.host}/`;
    e("new-rule-name").value = "Manual rule for " + url.host;

    e("add-new-rule-button").addEventListener("click", function() {
      const params = {
        host : e("new-rule-host").value,
        redirectTo : e("new-rule-redirect").value,
        urlMatcher : e("new-rule-regex").value
      };
      sendMessage("add_new_rule", params, function() {
        location.reload();
      });
    });

    e("cancel-new-rule").addEventListener("click", function() {
      show(e("add-rule-link"));
      hide(e("add-new-rule-div"));
    });

    e("new-rule-show-advanced-link").addEventListener("click", function() {
      show(e("new-rule-advanced"));
      hide(e("new-rule-regular-text"));
    });

    e("new-rule-hide-advanced-link").addEventListener("click", function() {
      hide(e("new-rule-advanced"));
      show(e("new-rule-regular-text"));
    });
  });
}

function toggleHttpNowhere() {
  getOption_('httpNowhere', false, function(item) {
    setOption_('httpNowhere', !item.httpNowhere);
  });
}

function getOption_(opt, defaultOpt, callback) {
  var details = {};
  details[opt] = defaultOpt;
  sendMessage("get_option", details, callback);
}

function setOption_(opt, value, callback) {
  var details = {};
  details[opt] = value;
  sendMessage("set_option", details, callback);
}

function getTab(callback) {
  let url = new URL(window.location.href);
  if (url.searchParams.has('tabId')) {
    let parentId = Number(url.searchParams.get('tabId'));
    return chrome.tabs.get(parentId, callback);
  }
  chrome.tabs.query({active: true, lastFocusedWindow: true}, tabs => callback(tabs[0]));
}
