/* global url */
const MODE = "mode";
const MODE_OFF = "off";
const MODE_BLACKLIST = "blacklist";

const BLACKLIST = "blacklist";
const WHITELIST = "whitelist";

const ICON           = "icon.svg";
const ICON_OFF       = "icon-off.svg";
const ICON_BLACKLIST = "icon-blacklist.svg";
const ICON_WHITELIST = "icon-whitelist.svg";

const MAX_NOTIFICATION_URL_LENGTH = 100;

const GLOBAL_BLACKLIST = [
    "/abp",
    "/account",
    "/auth",
    "/cookie",
    "/download",
    "/login",
    "/logout",
    "/preferences",
    "/profile",
    "/register",
    "/signin",
    "/signoff",
    "/signon",
    "/signout",
    "/signup",
    "/subscribe",
    "/verification",
];

let currentMode = undefined;
let blacklist = [];
let whitelist = [];

browser.storage.local.get([MODE, BLACKLIST, WHITELIST])
    .then(
        (result) => {
            if (result[BLACKLIST] === undefined) {
                browser.storage.local.set({[BLACKLIST]: GLOBAL_BLACKLIST});
            } else {
                updateBlacklist(result[BLACKLIST]);
            }

            if (result[WHITELIST] === undefined) {
                browser.storage.local.set({[WHITELIST]: []});
            } else {
                updateWhitelist(result[WHITELIST]);
            }

            if (result[MODE] === undefined) {
                browser.storage.local.set({[MODE]: MODE_BLACKLIST});
            } else if (result[MODE] === MODE_OFF) {
                disableSkipping();
            } else {
                enableSkipping(result[MODE]);
            }
        }
    );

browser.storage.onChanged.addListener(
    (changes) => {
        if (changes[BLACKLIST]) {
            updateBlacklist(changes[BLACKLIST].newValue);
        }

        if (changes[WHITELIST]) {
            updateWhitelist(changes[WHITELIST].newValue);
        }

        if (changes[MODE]) {
            if (changes[MODE].newValue === MODE_OFF) {
                disableSkipping();
            } else {
                enableSkipping(changes[MODE].newValue);
            }
        }
    }
);

function updateBlacklist(newBlacklist) {
    blacklist = newBlacklist.filter(Boolean);
}

function updateWhitelist(newWhitelist) {
    whitelist = newWhitelist.filter(Boolean);
}

function enableSkipping(mode) {
    browser.webRequest.onBeforeRequest.removeListener(maybeRedirect);

    currentMode = mode;
    if (mode === MODE_BLACKLIST) {
        browser.webRequest.onBeforeRequest.addListener(
            maybeRedirect,
            {urls: ["<all_urls>"], types: ["main_frame"]},
            ["blocking"]
        );
        browser.browserAction.setIcon({path: ICON_BLACKLIST});
    } else {
        browser.webRequest.onBeforeRequest.addListener(
            maybeRedirect,
            {urls: whitelist, types: ["main_frame"]},
            ["blocking"]
        );
        browser.browserAction.setIcon({path: ICON_WHITELIST});
    }

    browser.browserAction.setTitle({title: "Skip Redirect is enabled, click to disable"});
}

function disableSkipping() {
    browser.webRequest.onBeforeRequest.removeListener(maybeRedirect);

    browser.browserAction.setIcon({path: ICON_OFF});
    browser.browserAction.setTitle({title: "Skip Redirect is disabled, click to enable"});
}

function maybeRedirect(requestDetails) {
    if (requestDetails.tabId === -1 || requestDetails.method === "POST") {
        return;
    }

    let exceptions = [];
    if (currentMode === MODE_BLACKLIST) {
        exceptions = blacklist;
    }

    const redirectTarget = url.getRedirectTarget(requestDetails.url, exceptions);
    if (redirectTarget == requestDetails.url) {
        return;
    }

    notifySkip(requestDetails.url, redirectTarget);

    return {
        redirectUrl: redirectTarget,
    };
}

function notifySkip(from, to) {
    browser.notifications.create("notify-skip", {
        type: "basic",
        iconUrl: browser.extension.getURL(ICON),
        title: "Skipped Redirect",
        message: cleanUrl(from) + "\n->\n" + cleanUrl(to),
    });
}

function cleanUrl(string) {
    if (string.length > MAX_NOTIFICATION_URL_LENGTH) {
        string = string.substring(0, MAX_NOTIFICATION_URL_LENGTH - 3) + "...";
    }

    return string.replace(/&/g, "&amp;");
}

@@ -2622,32 +2622,72 @@
 );%0A    %7D else %7B%0A
+        if (whitelist.length %3E 0) %7B%0A    
         browser.
@@ -2730,32 +2730,36 @@
 er(%0A            
+   
+ 
 maybeRedirect,%0A 
@@ -2749,32 +2749,36 @@
  maybeRedirect,%0A
+    
             %7Burl
@@ -2819,32 +2819,36 @@
 %5D%7D,%0A            
+   
+ 
 %5B%22blocking%22%5D%0A   
@@ -2844,34 +2844,49 @@
 cking%22%5D%0A        
-);
+    );%0A        %7D%0A
 %0A        browser

Fix whitelist mode with empty whitelist