/*
 * Copyright (C) 2013, 2015, 2018 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.CookieStorageContentView = class CookieStorageContentView extends WI.ContentView
{
    constructor(representedObject)
    {
        super(representedObject);

        this.element.classList.add("cookie-storage");

        this._cookies = [];
        this._filteredCookies = [];
        this._sortComparator = null;
        this._table = null;
        this._knownCells = new WeakSet;

        this._emptyFilterResultsMessageElement = null;

        this._filterBarNavigationItem = new WI.FilterBarNavigationItem;
        this._filterBarNavigationItem.filterBar.addEventListener(WI.FilterBar.Event.FilterDidChange, this._handleFilterBarFilterDidChange, this);

        if (InspectorBackend.hasCommand("Page.setCookie")) {
            this._setCookieButtonNavigationItem = new WI.ButtonNavigationItem("cookie-storage-set-cookie", WI.UIString("Add Cookie"), "Images/Plus15.svg", 15, 15);
            this._setCookieButtonNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._handleSetCookieButtonClick, this);
        }

        if (InspectorBackend.hasCommand("Page.getCookies")) {
            this._refreshButtonNavigationItem = new WI.ButtonNavigationItem("cookie-storage-refresh", WI.UIString("Refresh"), "Images/ReloadFull.svg", 13, 13);
            this._refreshButtonNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._refreshButtonClicked, this);
        }

        if (InspectorBackend.hasCommand("Page.deleteCookie")) {
            this._clearButtonNavigationItem = new WI.ButtonNavigationItem("cookie-storage-clear", WI.UIString("Clear Cookies"), "Images/NavigationItemTrash.svg", 15, 15);
            this._clearButtonNavigationItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.Low;
            this._clearButtonNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._handleClearNavigationItemClicked, this);
        }
    }

    // Public

    get navigationItems()
    {
        let navigationItems = [];
        navigationItems.push(this._filterBarNavigationItem);
        navigationItems.push(new WI.DividerNavigationItem);
        if (this._setCookieButtonNavigationItem)
            navigationItems.push(this._setCookieButtonNavigationItem);
        if (this._refreshButtonNavigationItem)
            navigationItems.push(this._refreshButtonNavigationItem);
        if (this._clearButtonNavigationItem)
            navigationItems.push(this._clearButtonNavigationItem);
        return navigationItems;
    }

    saveToCookie(cookie)
    {
        cookie.type = WI.ContentViewCookieType.CookieStorage;
        cookie.host = this.representedObject.host;
    }

    get scrollableElements()
    {
        if (!this._table)
            return [];
        return [this._table.scrollContainer];
    }

    get canFocusFilterBar()
    {
        return true;
    }

    focusFilterBar()
    {
        this._filterBarNavigationItem.filterBar.focus();
    }

    handleCopyEvent(event)
    {
        if (!this._table || !this._table.selectedRows.length)
            return;

        let cookies = this._cookiesAtIndexes(this._table.selectedRows);
        if (!cookies.length)
            return;

        event.clipboardData.setData("text/plain", this._formatCookiesAsText(cookies));
        event.stopPropagation();
        event.preventDefault();
    }

    // Table dataSource

    tableIndexForRepresentedObject(table, object)
    {
        let index = this._filteredCookies.indexOf(object);
        console.assert(index >= 0);
        return index;
    }

    tableRepresentedObjectForIndex(table, index)
    {
        console.assert(index >= 0 && index < this._filteredCookies.length);
        return this._filteredCookies[index];
    }

    tableNumberOfRows(table)
    {
        return this._filteredCookies.length;
    }

    tableSortChanged(table)
    {
        this._generateSortComparator();

        if (!this._sortComparator)
            return;

        this._updateSort();
        this._updateFilteredCookies();
        this._updateEmptyFilterResultsMessage();
        this._table.reloadData();
    }

    // Table delegate

    tableCellContextMenuClicked(table, cell, column, rowIndex, event)
    {
        let contextMenu = WI.ContextMenu.createFromEvent(event);

        contextMenu.appendSeparator();

        if (InspectorBackend.hasCommand("Page.setCookie") && column.identifier !== "size") {
            contextMenu.appendItem(WI.UIString("Edit %s").format(column.name), () => {
                this._showCookiePopover(cell, this._filteredCookies[rowIndex], column.identifier);
            });
        }

        contextMenu.appendItem(WI.UIString("Copy"), () => {
            let rowIndexes;
            if (table.isRowSelected(rowIndex))
                rowIndexes = table.selectedRows;
            else
                rowIndexes = [rowIndex];

            let cookies = this._cookiesAtIndexes(rowIndexes);
            InspectorFrontendHost.copyText(this._formatCookiesAsText(cookies));
        });

        if (InspectorBackend.hasCommand("Page.deleteCookie")) {
            contextMenu.appendItem(WI.UIString("Delete"), () => {
                if (table.isRowSelected(rowIndex))
                    table.removeSelectedRows();
                else
                    table.removeRow(rowIndex);
            });
        }

        contextMenu.appendSeparator();
    }

    tableDidRemoveRows(table, rowIndexes)
    {
        if (!rowIndexes.length)
            return;

        for (let i = rowIndexes.length - 1; i >= 0; --i) {
            let rowIndex = rowIndexes[i];
            let cookie = this._filteredCookies[rowIndex];
            console.assert(cookie, "Missing cookie for row " + rowIndex);
            if (!cookie)
                continue;

            this._filteredCookies.splice(rowIndex, 1);
            this._cookies.remove(cookie);

            let target = WI.assumingMainTarget();
            target.PageAgent.deleteCookie(cookie.name, cookie.url);
        }
    }

    tablePopulateCell(table, cell, column, rowIndex)
    {
        let cookie = this._filteredCookies[rowIndex];

        cell.textContent = this._formatCookiePropertyForColumn(cookie, column);

        if (!this._knownCells.has(cell)) {
            this._knownCells.add(cell);

            cell.addEventListener("dblclick", (event) => {
                if (column.identifier === "size") {
                    InspectorFrontendHost.beep();
                    return;
                }

                this._showCookiePopover(cell, cookie, column.identifier);
            });
        }

        return cell;
    }

    // Popover delegate

    willDismissPopover(popover)
    {
        if (popover instanceof WI.CookiePopover) {
            this._willDismissCookiePopover(popover);
            return;
        }

        console.assert();
    }

    // Protected

    initialLayout()
    {
        super.initialLayout();

        this._table = new WI.Table("cookies-table", this, this, 20);
        this._table.allowsMultipleSelection = true;

        this._nameColumn = new WI.TableColumn("name", WI.UIString("Name"), {
            minWidth: 70,
            maxWidth: 300,
            initialWidth: 200,
            resizeType: WI.TableColumn.ResizeType.Locked,
        });

        this._valueColumn = new WI.TableColumn("value", WI.UIString("Value"), {
            minWidth: 100,
            maxWidth: 600,
            initialWidth: 200,
            hideable: false,
        });

        this._domainColumn = new WI.TableColumn("domain", WI.unlocalizedString("Domain"), {
            minWidth: 100,
            maxWidth: 200,
            initialWidth: 120,
        });

        this._pathColumn = new WI.TableColumn("path", WI.unlocalizedString("Path"), {
            minWidth: 50,
            maxWidth: 300,
            initialWidth: 100,
        });

        this._expiresColumn = new WI.TableColumn("expires", WI.unlocalizedString("Expires"), {
            minWidth: 100,
            maxWidth: 200,
            initialWidth: 150,
        });

        this._sizeColumn = new WI.TableColumn("size", WI.UIString("Size"), {
            minWidth: 50,
            maxWidth: 80,
            initialWidth: 65,
            align: "right",
        });

        this._secureColumn = new WI.TableColumn("secure", WI.unlocalizedString("Secure"), {
            minWidth: 70,
            maxWidth: 70,
            align: "center",
        });

        this._httpOnlyColumn = new WI.TableColumn("httpOnly", WI.unlocalizedString("HttpOnly"), {
            minWidth: 80,
            maxWidth: 80,
            align: "center",
        });

        this._sameSiteColumn = new WI.TableColumn("sameSite", WI.unlocalizedString("SameSite"), {
            minWidth: 40,
            maxWidth: 80,
            initialWidth: 70,
            align: "center",
        });

        this._table.addColumn(this._nameColumn);
        this._table.addColumn(this._valueColumn);
        this._table.addColumn(this._domainColumn);
        this._table.addColumn(this._pathColumn);
        this._table.addColumn(this._expiresColumn);
        this._table.addColumn(this._sizeColumn);
        this._table.addColumn(this._secureColumn);
        this._table.addColumn(this._httpOnlyColumn);
        this._table.addColumn(this._sameSiteColumn);

        if (!this._table.sortColumnIdentifier) {
            this._table.sortOrder = WI.Table.SortOrder.Ascending;
            this._table.sortColumnIdentifier = "name";
         }

        this.addSubview(this._table);

        this._table.element.addEventListener("keydown", this._handleTableKeyDown.bind(this));

        this._reloadCookies();
    }

    // Private

    _getCookiesForHost(cookies, host)
    {
        let resourceMatchesStorageDomain = (resource) => {
            let urlComponents = resource.urlComponents;
            return urlComponents && urlComponents.host && urlComponents.host === host;
        };

        let allResources = [];
        for (let frame of WI.networkManager.frames) {
            // The main resource isn't in the list of resources, so add it as a candidate.
            allResources.push(frame.mainResource, ...frame.resourceCollection);
        }

        let resourcesForDomain = allResources.filter(resourceMatchesStorageDomain);

        let cookiesForDomain = cookies.filter((cookie) => {
            return resourcesForDomain.some((resource) => {
                return WI.CookieStorageObject.cookieMatchesResourceURL(cookie, resource.url);
            });
        });
        return cookiesForDomain;
    }

    _generateSortComparator()
    {
        let sortColumnIdentifier = this._table.sortColumnIdentifier;
        if (!sortColumnIdentifier) {
            this._sortComparator = null;
            return;
        }

        let comparator = null;

        switch (sortColumnIdentifier) {
        case "name":
        case "value":
        case "domain":
        case "path":
        case "sameSite":
            comparator = (a, b) => (a[sortColumnIdentifier] || "").extendedLocaleCompare(b[sortColumnIdentifier] || "");
            break;

        case "size":
        case "httpOnly":
        case "secure":
            comparator = (a, b) => a[sortColumnIdentifier] - b[sortColumnIdentifier];
            break;

        case "expires":
            comparator = (a, b) => {
                if (!a.expires)
                    return 1;
                if (!b.expires)
                    return -1;
                return a.expires - b.expires;
            };
            break;

        default:
            console.assert("Unexpected sort column", sortColumnIdentifier);
            return;
        }

        let reverseFactor = this._table.sortOrder === WI.Table.SortOrder.Ascending ? 1 : -1;
        this._sortComparator = (a, b) => reverseFactor * comparator(a, b);
    }

    _showCookiePopover(targetElement, cookie, columnIdentifier) {
        console.assert(!this._editingCookie);
        this._editingCookie = cookie;

        let options = {};
        if (columnIdentifier) {
            switch (columnIdentifier) {
            case "name":
            case "value":
            case "domain":
            case "path":
            case "secure":
                options.focusField = columnIdentifier;
                break;

            case "expires":
                options.focusField = this._editingCookie.session ? "session" : "expires";
                break;

            case "httpOnly":
                options.focusField = "http-only";
                break;

            case "sameSite":
                options.focusField = "same-site";
                break;

            default:
                console.assert();
                break;
            }
        }

        let popover = new WI.CookiePopover(this);
        popover.show(this._editingCookie, targetElement, [WI.RectEdge.MAX_Y, WI.RectEdge.MIN_Y, WI.RectEdge.MIN_X, WI.RectEdge.MAX_X], options);
    }

    async _willDismissCookiePopover(popover)
    {
        let editingCookie = this._editingCookie;
        this._editingCookie = null;

        let serializedData = popover.serializedData;
        if (!serializedData) {
            InspectorFrontendHost.beep();
            return;
        }

        let cookieToSet = WI.Cookie.fromPayload(serializedData);

        let cookieProtocolPayload = cookieToSet.toProtocol();
        if (!cookieProtocolPayload) {
            InspectorFrontendHost.beep();
            return;
        }

        let target = WI.assumingMainTarget();

        let promises = [];
        if (editingCookie)
            promises.push(target.PageAgent.deleteCookie(editingCookie.name, editingCookie.url));
        promises.push(target.PageAgent.setCookie(cookieProtocolPayload));
        promises.push(this._reloadCookies());
        await Promise.all(promises);

        let index = this._filteredCookies.findIndex((existingCookie) => cookieToSet.equals(existingCookie));
        if (index >= 0)
            this._table.selectRow(index);
    }

    _handleFilterBarFilterDidChange(event)
    {
        this._updateFilteredCookies();
        this._updateEmptyFilterResultsMessage();
        this._table.reloadData();
    }

    _handleSetCookieButtonClick(event)
    {
        this._showCookiePopover(this._setCookieButtonNavigationItem.element, null, "name");
    }

    _refreshButtonClicked(event)
    {
        this._reloadCookies();
    }

    _handleClearNavigationItemClicked(event)
    {
        let target = WI.assumingMainTarget();
        for (let cookie of this._cookies)
            target.PageAgent.deleteCookie(cookie.name, cookie.url);

        this._reloadCookies();
    }

    _reloadCookies()
    {
        let target = WI.assumingMainTarget();
        if (!target.hasCommand("Page.getCookies"))
            return;

        target.PageAgent.getCookies().then((payload) => {
            this._cookies = this._getCookiesForHost(payload.cookies.map(WI.Cookie.fromPayload), this.representedObject.host);
            this._updateSort();
            this._updateFilteredCookies();
            this._updateEmptyFilterResultsMessage();
            this._table.reloadData();
        }).catch((error) => {
            console.error("Could not fetch cookies: ", error);
        });
    }

    _updateSort()
    {
        if (!this._sortComparator)
            return;

        this._cookies.sort(this._sortComparator);
    }

    _updateFilteredCookies()
    {
        this._filteredCookies = this._cookies;

        let filterBar = this._filterBarNavigationItem.filterBar;
        filterBar.invalid = false;

        let filterText = filterBar.filters.text;
        if (!filterText)
            return;

        let regex = WI.SearchUtilities.filterRegExpForString(filterText, WI.SearchUtilities.defaultSettings);
        if (!regex) {
            filterBar.invalid = true;
            return;
        }

        this._filteredCookies = this._filteredCookies.filter((cookie) => {
            for (let column of this._table.columns) {
                let text = this._formatCookiePropertyForColumn(cookie, column);
                if (text && regex.test(text))
                    return true;
            }
            return false;
        });
    }

    _updateEmptyFilterResultsMessage()
    {
        if (this._filteredCookies.length || !this._filterBarNavigationItem.filterBar.filters.text) {
            if (this._emptyFilterResultsMessageElement)
                this._emptyFilterResultsMessageElement.remove();
            this._emptyFilterResultsMessageElement = null;
        } else {
            if (!this._emptyFilterResultsMessageElement) {
                let buttonElement = document.createElement("button");
                buttonElement.textContent = WI.UIString("Clear Filters");
                buttonElement.addEventListener("click", (event) => {
                    this._filterBarNavigationItem.filterBar.clear();
                });

                this._emptyFilterResultsMessageElement = WI.createMessageTextView(WI.UIString("No Filter Results"));
                this._emptyFilterResultsMessageElement.appendChild(buttonElement);
            }

            this.element.appendChild(this._emptyFilterResultsMessageElement);
        }
    }

    _handleTableKeyDown(event)
    {
        if (event.keyCode === WI.KeyboardShortcut.Key.Backspace.keyCode || event.keyCode === WI.KeyboardShortcut.Key.Delete.keyCode) {
            if (InspectorBackend.hasCommand("Page.deleteCookie"))
                this._table.removeSelectedRows();
            else
                InspectorFrontendHost.beep();
        }
    }

    _cookiesAtIndexes(indexes)
    {
        if (!this._filteredCookies.length)
            return [];
        return indexes.map((index) => this._filteredCookies[index]);
    }

    _formatCookiesAsText(cookies)
    {
        let visibleColumns = this._table.columns.filter((column) => !column.hidden);
        if (!visibleColumns.length)
            return "";

        let lines = cookies.map((cookie) => {
            const usePunctuation = false;
            let values = visibleColumns.map((column) => this._formatCookiePropertyForColumn(cookie, column, usePunctuation));
            return values.join("\t");
        });

        return lines.join("\n");
    }

    _formatCookiePropertyForColumn(cookie, column, usePunctuation = true)
    {
        const checkmark = "\u2713";
        const missingValue = usePunctuation ? emDash : "";
        const missingCheckmark = usePunctuation ? zeroWidthSpace : "";

        switch (column.identifier) {
        case "name":
            return cookie.name;
        case "value":
            return cookie.value;
        case "domain":
            return cookie.domain || missingValue;
        case "path":
            return cookie.path || missingValue;
        case "expires":
            return (!cookie.session && cookie.expires) ? cookie.expires.toLocaleString() : WI.UIString("Session");
        case "size":
            return Number.bytesToString(cookie.size);
        case "secure":
            return cookie.secure ? checkmark : missingCheckmark;
        case "httpOnly":
            return cookie.httpOnly ? checkmark : missingCheckmark;
        case "sameSite":
            return cookie.sameSite === WI.Cookie.SameSiteType.None ? missingValue : WI.Cookie.displayNameForSameSiteType(cookie.sameSite);
        }

        console.assert("Unexpected table column " + column.identifier);
        return "";
    }
};

WI.CookieType = {
    Request: 0,
    Response: 1
};
