/*
 * Copyright (C) 2020 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

WI.CookiePopover = class CookiePopover extends WI.Popover
{
    constructor(delegate)
    {
        super(delegate);

        this._nameInputElement = null;
        this._valueInputElement = null;
        this._domainInputElement = null;
        this._pathInputElement = null;
        this._sessionCheckboxElement = null;
        this._expiresInputElement = null;
        this._httpOnlyCheckboxElement = null;
        this._secureCheckboxElement = null;
        this._sameSiteSelectElement = null;

        this._serializedDataWhenShown = null;

        this.windowResizeHandler = this._presentOverTargetElement.bind(this);
    }

    // Public

    get serializedData()
    {
        if (!this._targetElement)
            return null;

        let name = this._nameInputElement.value || this._nameInputElement.placeholder;
        if (!name)
            return null;

        let value = this._valueInputElement.value || this._valueInputElement.placeholder;
        if (!value)
            return null;

        let domain = this._domainInputElement.value || this._domainInputElement.placeholder;
        if (!domain)
            return null;

        let path = this._pathInputElement.value || this._pathInputElement.placeholder;
        if (!path)
            return null;

        let session = this._sessionCheckboxElement.checked;
        let expires = this._parseExpires();
        if (!session && isNaN(expires))
            return null;

        // If a full URL is entered in the domain input, parse it to get just the domain.
        try {
            let url = new URL(domain);
            domain = url.hostname;
        } catch { }

        if (!path.startsWith("/"))
            path = "/" + path;

        let data = {
            name,
            value,
            domain,
            path,
            httpOnly: this._httpOnlyCheckboxElement.checked,
            secure: this._secureCheckboxElement.checked,
            sameSite: this._sameSiteSelectElement.value,
        };

        if (session)
            data.session = true;
        else
            data.expires = expires;

        if (JSON.stringify(data) === JSON.stringify(this._serializedDataWhenShown))
            return null;

        return data;
    }

    show(cookie, targetElement, preferredEdges)
    {
        console.assert(!cookie || cookie instanceof WI.Cookie, cookie);
        console.assert(targetElement instanceof Element, targetElement);
        console.assert(Array.isArray(preferredEdges), preferredEdges);

        this._targetElement = targetElement;
        this._preferredEdges = preferredEdges;

        let data = {};
        if (cookie) {
            data.name = cookie.name;
            data.value = cookie.value;
            data.domain = cookie.domain;
            data.path = cookie.path;
            data.expires = (cookie.expires || this._defaultExpires()).toLocaleString();
            data.session = cookie.session;
            data.httpOnly = cookie.httpOnly;
            data.secure = cookie.secure;
            data.sameSite = cookie.sameSite;
        } else {
            let urlComponents = WI.networkManager.mainFrame.mainResource.urlComponents;
            data.name = WI.unlocalizedString("name");
            data.value = WI.unlocalizedString("value");
            data.domain = urlComponents.host;
            data.path = urlComponents.path;
            data.expires = this._defaultExpires().toLocaleString();
            data.session = true;
            data.httpOnly = false;
            data.secure = false;
            data.sameSite = WI.Cookie.SameSiteType.None;
        }

        let popoverContentElement = document.createElement("div");
        popoverContentElement.className = "cookie-popover-content";

        let tableElement = popoverContentElement.appendChild(document.createElement("table"));

        function createRow(id, label, editorElement) {
            id = `cookie-popover-${id}-editor`;

            let rowElement = tableElement.appendChild(document.createElement("tr"));

            let headerElement = rowElement.appendChild(document.createElement("th"));

            let labelElement = headerElement.appendChild(document.createElement("label"));
            labelElement.setAttribute("for", id);
            labelElement.textContent = label;

            let dataElement = rowElement.appendChild(document.createElement("td"));

            editorElement.id = id;
            dataElement.appendChild(editorElement);

            return {rowElement};
        }

        let boundHandleInputKeyDown = this._handleInputKeyDown.bind(this);

        function createInputRow(id, label, type, value) {
            let inputElement = document.createElement("input");
            inputElement.type = type;

            if (type === "checkbox")
                inputElement.checked = value;
            else {
                if (cookie)
                    inputElement.value = value;
                inputElement.placeholder = value;
                inputElement.addEventListener("keydown", boundHandleInputKeyDown);
            }

            let rowElement = createRow(id, label, inputElement).rowElement;

            return {inputElement, rowElement};
        }

        this._nameInputElement = createInputRow("name", WI.UIString("Name"), "text", data.name).inputElement;

        this._valueInputElement = createInputRow("value", WI.UIString("Value"), "text", data.value).inputElement;

        this._domainInputElement = createInputRow("domain", WI.unlocalizedString("Domain"), "text", data.domain).inputElement;

        this._pathInputElement = createInputRow("path", WI.unlocalizedString("Path"), "text", data.path).inputElement;

        this._sessionCheckboxElement = createInputRow("session", WI.unlocalizedString("Session"), "checkbox", data.session).inputElement;

        let expiresInputRow = createInputRow("expires", WI.unlocalizedString("Expires"), "datetime-local", data.expires);
        this._expiresInputElement = expiresInputRow.inputElement;
        this._expiresInputElement.addEventListener("input", (event) => {
            this._expiresInputElement.classList.toggle("invalid", isNaN(this._parseExpires()));
        });

        this._httpOnlyCheckboxElement = createInputRow("http-only", WI.unlocalizedString("HttpOnly"), "checkbox", data.httpOnly).inputElement;

        this._secureCheckboxElement = createInputRow("secure", WI.unlocalizedString("Secure"), "checkbox", data.secure).inputElement;

        this._sameSiteSelectElement = document.createElement("select");
        for (let sameSiteType of Object.values(WI.Cookie.SameSiteType)) {
            let optionElement = this._sameSiteSelectElement.appendChild(document.createElement("option"));
            optionElement.textContent = sameSiteType;
        }
        createRow("same-site", WI.unlocalizedString("SameSite"), this._sameSiteSelectElement);

        let toggleExpiresRow = () => {
            expiresInputRow.rowElement.hidden = this._sessionCheckboxElement.checked;

            this.update();
        };

        this._sessionCheckboxElement.addEventListener("change", (event) => {
            toggleExpiresRow();
        });

        toggleExpiresRow();

        this._serializedDataWhenShown = this.serializedData;

        this.content = popoverContentElement;
        this._presentOverTargetElement();
    }

    // Private

    _presentOverTargetElement()
    {
        if (!this._targetElement)
            return;

        let targetFrame = WI.Rect.rectFromClientRect(this._targetElement.getBoundingClientRect());
        this.present(targetFrame.pad(2), this._preferredEdges);
    }

    _defaultExpires()
    {
        return new Date(Date.now() + (1000 * 60 * 60 * 24)); // one day in the future
    }

    _parseExpires()
    {
        let timestamp = Date.parse(this._expiresInputElement.value || this._expiresInputElement.placeholder);
        if (timestamp < Date.now())
            return NaN;
        return timestamp;
    }

    _handleInputKeyDown(event)
    {
        if (event.key === "Enter" || event.key === "Esc")
            this.dismiss();
    }
};
