if (self.testRunner)
    testRunner.waitUntilDone();

var g_childWindow;
var g_cachedCookies;
var g_baseURLWhenFetchingCookies = "";
var g_baseDocumentWhenFetchingDOMCookies;

function createCookie(name, value, additionalProperties)
{
    let cookie = `${name}=${value}`;
    for (let propertyName in additionalProperties) {
        cookie += `; ${propertyName}`;
        let propertyValue = additionalProperties[propertyName];
        if (propertyValue != undefined)
            cookie += "=" + propertyValue;
    }
    return cookie;
}

function setBaseDocumentWhenFetchingDOMCookies(aDocument)
{
    g_baseDocumentWhenFetchingDOMCookies = aDocument;
}

function setDOMCookie(name, value, additionalProperties={})
{
    g_baseDocumentWhenFetchingDOMCookies.cookie = createCookie(name, value, additionalProperties);
}

function getDOMCookies()
{
    if (!g_baseDocumentWhenFetchingDOMCookies)
        g_baseDocumentWhenFetchingDOMCookies = document;
    if (!g_baseDocumentWhenFetchingDOMCookies.cookie)
        return {};
    let cookies = g_baseDocumentWhenFetchingDOMCookies.cookie.split("; ");
    let result = {};
    for (let keyAndValuePair of cookies) {
        let [key, value] = keyAndValuePair.split("=");
        result[key] = value;
    }
   return result;
}

async function setCookie(name, value, additionalProperties={})
{
    invalidateCachedCookies();

    let cookie = createCookie(name, value, additionalProperties);
    let promise = new Promise((resolved, rejected) => {
        let xhr = new XMLHttpRequest;
        xhr.open("GET", "/cookies/resources/setCookies.cgi");
        xhr.setRequestHeader("SET-COOKIE", cookie);
        xhr.onload = () => resolved(xhr.responseText);
        xhr.onerror = rejected;
        xhr.send(null);
    });
    return promise;
}

function disableSetAlwaysAcceptCookies() {
    if (window.testRunner)
        testRunner.setAlwaysAcceptCookies(false);
}

async function resetCookies(urls)
{
    let testingURLs = [
        "http://127.0.0.1:8000",
        "http://localhost:8000",
    ];

    urls = urls || testingURLs;
    console.assert(urls.length);

    function setUp() {
        return new Promise((resolve) => {
            if (window.testRunner) {
                testRunner.setAlwaysAcceptCookies(true);
                internals.settings.setJavaScriptCanOpenWindowsAutomatically(true);
            }
            resolve();
        });
    }

    function cleanUp() {
        return new Promise((resolve) => {
            disableSetAlwaysAcceptCookies();
            g_childWindow.close();
            g_childWindow = null;
            resolve();
        });
    }

    let promise = setUp();
    for (let url of urls) {
        promise = promise.then(() => {
            return new Promise((resolve, reject) => {
                // FIXME: For some reason we get a SecurityError when passing childWindow to resolve() in Safari Version 11.0.3 (13604.5.6)
                // and not in Chrome Canary 67.0.3390.0 (why?). As a workaround, store the child window reference in a global variable.
                window.addEventListener("message", (messageEvent) => resolve(messageEvent), {capture: true, once: true});
                g_childWindow = window.open(url + "/cookies/resources/cookie-utility.py?queryfunction=deleteCookiesAndPostMessage", "reset");
                if (!g_childWindow)
                    reject(null);
            });
        });
    }
    return promise.then(cleanUp);
}

async function resetCookiesForCurrentOrigin()
{
    invalidateCachedCookies();

    let promise = new Promise((resolved, rejected) => {
        let xhr = new XMLHttpRequest;
        xhr.open("GET", "/cookies/resources/cookie-utility.py?queryfunction=deleteCookies");
        xhr.onload = (progressEvent) => {
            disableSetAlwaysAcceptCookies();
            resolved(progressEvent);
        };
        xhr.onerror = (progressEvent) => {
            disableSetAlwaysAcceptCookies();
            rejected(progressEvent);
        };

        if (window.testRunner)
            testRunner.setAlwaysAcceptCookies(true);

        xhr.send(null);
    });
    return promise;
}

function setBaseURLWhenFetchingCookies(baseURLWhenFetchingCookies)
{
    g_baseURLWhenFetchingCookies = baseURLWhenFetchingCookies;
}

function invalidateCachedCookies()
{
    g_cachedCookies = null;
}

function _setCachedCookiesJSON(cookies)
{
    g_cachedCookies = JSON.parse(cookies);
}

async function getCookies()
{
    if (g_cachedCookies)
        return g_cachedCookies;

    let promise = new Promise((resolved, rejected) => {
        let xhr = new XMLHttpRequest;
        xhr.open("GET", `${g_baseURLWhenFetchingCookies}/cookies/resources/echo-json.py`);
        xhr.onload = () => resolved(xhr.responseText ? JSON.parse(xhr.responseText) : {});
        xhr.onerror = () => rejected({});
        xhr.send(null);
    });
    g_cachedCookies = await promise;
    return g_cachedCookies;
}

async function shouldNotHaveCookie(name)
{
    let cookies = await getCookies();
    let value = cookies[name];
    if (value == undefined)
        testPassed(`Do not have cookie "${name}".`);
    else
        testFailed(`Should not have cookie "${name}". But do with value ${value}.`);
}

async function shouldHaveCookie(name)
{
    let cookies = await getCookies();
    let value = cookies[name];
    if (value == undefined)
        testFailed(`Should have cookie "${name}". But do not.`);
    else
        testPassed(`Has cookie "${name}".`);
}

async function shouldHaveCookieWithValue(name, expectedValue)
{
    console.assert(expectedValue !== undefined);
    let cookies = await getCookies();
    let value = cookies[name];
    if (value == undefined)
        testFailed(`Should have cookie "${name}". But do not.`);
    else if (value === expectedValue)
        testPassed(`Has cookie "${name}" with value ${value}.`);
    else
        testFailed(`Cookie "${name}" should have value ${expectedValue}. Was ${value}.`);
}

function shouldNotHaveDOMCookie(name)
{
    let cookies = getDOMCookies();
    let value = cookies[name];
    if (value == undefined)
        testPassed(`Do not have DOM cookie "${name}".`);
    else
        testFailed(`Should not have DOM cookie "${name}". But do with value ${value}.`);
}

function shouldHaveDOMCookie(name)
{
    let cookies = getDOMCookies();
    let value = cookies[name];
    if (value == undefined)
        testFailed(`Should have DOM cookie "${name}". But do not.`);
    else
        testPassed(`Has DOM cookie "${name}".`);
}

function shouldHaveDOMCookieWithValue(name, expectedValue)
{
    console.assert(expectedValue !== undefined);
    let cookies = getDOMCookies();
    let value = cookies[name];
    if (value == undefined)
        testFailed(`Should have DOM cookie "${name}". But do not.`);
    else if (value === expectedValue)
        testPassed(`Has DOM cookie "${name}" with value ${value}.`);
    else
        testFailed(`DOM cookie "${name}" should have value ${expectedValue}. Was ${value}.`);
}

function setCookieUsingWebSocketFromHost(host)
{
    var promise = new Promise(resolve => {
        var websocket = new WebSocket(`ws://${host}:8880/websocket/tests/hybi/cookie?set`);
        websocket.onclose = () => resolve();
    });
    return promise;
}

function createExpiresDateFromMaxAge(maxAgeInSeconds)
{
    let date = new Date();
    date.setTime(date.getTime() + (maxAgeInSeconds * 1000));
    return date.toUTCString();
}
