/*
 * Copyright (C) 2009 Apple Inc.  All rights reserved.
 * Copyright (C) 2009 Joseph Pecoraro
 * Copyright (C) 2010 Google 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.
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE 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 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.
 */

/**
 * @constructor
 * @extends {WebInspector.VBox}
 * @param {boolean} expandable
 * @param {function()=} refreshCallback
 * @param {function()=} selectedCallback
 */
WebInspector.CookiesTable = function(expandable, refreshCallback, selectedCallback)
{
    WebInspector.VBox.call(this);

    var readOnly = expandable;
    this._refreshCallback = refreshCallback;

    var columns = [
        {id: "name", title: WebInspector.UIString("Name"), sortable: true, disclosure: expandable, sort: WebInspector.DataGrid.Order.Ascending, longText: true, weight: 24},
        {id: "value", title: WebInspector.UIString("Value"), sortable: true, longText: true, weight: 34},
        {id: "domain", title: WebInspector.UIString("Domain"), sortable: true, weight: 7},
        {id: "path", title: WebInspector.UIString("Path"), sortable: true, weight: 7},
        {id: "expires", title: WebInspector.UIString("Expires / Max-Age"), sortable: true, weight: 7},
        {id: "size", title: WebInspector.UIString("Size"), sortable: true, align: WebInspector.DataGrid.Align.Right, weight: 7},
        {id: "httpOnly", title: WebInspector.UIString("HTTP"), sortable: true, align: WebInspector.DataGrid.Align.Center, weight: 7},
        {id: "secure", title: WebInspector.UIString("Secure"), sortable: true, align: WebInspector.DataGrid.Align.Center, weight: 7},
        {id: "sameSite", title: WebInspector.UIString("Same-Site"), sortable: true, align: WebInspector.DataGrid.Align.Center, weight: 7}
    ];

    if (readOnly)
        this._dataGrid = new WebInspector.DataGrid(columns);
    else
        this._dataGrid = new WebInspector.DataGrid(columns, undefined, this._onDeleteCookie.bind(this), refreshCallback, this._onContextMenu.bind(this));

    this._dataGrid.setName("cookiesTable");
    this._dataGrid.addEventListener(WebInspector.DataGrid.Events.SortingChanged, this._rebuildTable, this);

    if (selectedCallback)
        this._dataGrid.addEventListener(WebInspector.DataGrid.Events.SelectedNode, selectedCallback, this);

    this._nextSelectedCookie = /** @type {?WebInspector.Cookie} */ (null);

    this._dataGrid.asWidget().show(this.element);
    this._data = [];
}

WebInspector.CookiesTable.prototype = {
    /**
     * @param {?string} domain
     */
    _clearAndRefresh: function(domain)
    {
        this.clear(domain);
        this._refresh();
    },

    /**
     * @param {!WebInspector.ContextMenu} contextMenu
     * @param {!WebInspector.DataGridNode} node
     */
    _onContextMenu: function(contextMenu, node)
    {
        if (node === this._dataGrid.creationNode)
            return;
        var cookie = node.cookie;
        var domain = cookie.domain();
        if (domain)
            contextMenu.appendItem(WebInspector.UIString.capitalize("Clear ^all from \"%s\"", domain), this._clearAndRefresh.bind(this, domain));
        contextMenu.appendItem(WebInspector.UIString.capitalize("Clear ^all"), this._clearAndRefresh.bind(this, null));
    },

    /**
     * @param {!Array.<!WebInspector.Cookie>} cookies
     */
    setCookies: function(cookies)
    {
        this.setCookieFolders([{cookies: cookies}]);
    },

    /**
     * @param {!Array.<!{folderName: ?string, cookies: !Array.<!WebInspector.Cookie>}>} cookieFolders
     */
    setCookieFolders: function(cookieFolders)
    {
        this._data = cookieFolders;
        this._rebuildTable();
    },

    /**
     * @return {?WebInspector.Cookie}
     */
    selectedCookie: function()
    {
        var node = this._dataGrid.selectedNode;
        return node ? node.cookie : null;
    },

    /**
     * @param {?string=} domain
     */
    clear: function(domain)
    {
        for (var i = 0, length = this._data.length; i < length; ++i) {
            var cookies = this._data[i].cookies;
            for (var j = 0, cookieCount = cookies.length; j < cookieCount; ++j) {
                if (!domain || cookies[j].domain() === domain)
                    cookies[j].remove();
            }
        }
    },

    _rebuildTable: function()
    {
        var selectedCookie = this._nextSelectedCookie || this.selectedCookie();
        this._nextSelectedCookie = null;
        this._dataGrid.rootNode().removeChildren();
        for (var i = 0; i < this._data.length; ++i) {
            var item = this._data[i];
            if (item.folderName) {
                var groupData = {name: item.folderName, value: "", domain: "", path: "", expires: "", size: this._totalSize(item.cookies), httpOnly: "", secure: "", sameSite: ""};
                var groupNode = new WebInspector.DataGridNode(groupData);
                groupNode.selectable = true;
                this._dataGrid.rootNode().appendChild(groupNode);
                groupNode.element().classList.add("row-group");
                this._populateNode(groupNode, item.cookies, selectedCookie);
                groupNode.expand();
            } else
                this._populateNode(this._dataGrid.rootNode(), item.cookies, selectedCookie);
        }
    },

    /**
     * @param {!WebInspector.DataGridNode} parentNode
     * @param {?Array.<!WebInspector.Cookie>} cookies
     * @param {?WebInspector.Cookie} selectedCookie
     */
    _populateNode: function(parentNode, cookies, selectedCookie)
    {
        parentNode.removeChildren();
        if (!cookies)
            return;

        this._sortCookies(cookies);
        for (var i = 0; i < cookies.length; ++i) {
            var cookie = cookies[i];
            var cookieNode = this._createGridNode(cookie);
            parentNode.appendChild(cookieNode);
            if (selectedCookie && selectedCookie.name() === cookie.name() && selectedCookie.domain() === cookie.domain() && selectedCookie.path() === cookie.path())
                cookieNode.select();
        }
    },

    _totalSize: function(cookies)
    {
        var totalSize = 0;
        for (var i = 0; cookies && i < cookies.length; ++i)
            totalSize += cookies[i].size();
        return totalSize;
    },

    /**
     * @param {!Array.<!WebInspector.Cookie>} cookies
     */
    _sortCookies: function(cookies)
    {
        var sortDirection = this._dataGrid.isSortOrderAscending() ? 1 : -1;

        function compareTo(getter, cookie1, cookie2)
        {
            return sortDirection * (getter.apply(cookie1) + "").compareTo(getter.apply(cookie2) + "");
        }

        function numberCompare(getter, cookie1, cookie2)
        {
            return sortDirection * (getter.apply(cookie1) - getter.apply(cookie2));
        }

        function expiresCompare(cookie1, cookie2)
        {
            if (cookie1.session() !== cookie2.session())
                return sortDirection * (cookie1.session() ? 1 : -1);

            if (cookie1.session())
                return 0;

            if (cookie1.maxAge() && cookie2.maxAge())
                return sortDirection * (cookie1.maxAge() - cookie2.maxAge());
            if (cookie1.expires() && cookie2.expires())
                return sortDirection * (cookie1.expires() - cookie2.expires());
            return sortDirection * (cookie1.expires() ? 1 : -1);
        }

        var comparator;
        switch (this._dataGrid.sortColumnIdentifier()) {
            case "name": comparator = compareTo.bind(null, WebInspector.Cookie.prototype.name); break;
            case "value": comparator = compareTo.bind(null, WebInspector.Cookie.prototype.value); break;
            case "domain": comparator = compareTo.bind(null, WebInspector.Cookie.prototype.domain); break;
            case "path": comparator = compareTo.bind(null, WebInspector.Cookie.prototype.path); break;
            case "expires": comparator = expiresCompare; break;
            case "size": comparator = numberCompare.bind(null, WebInspector.Cookie.prototype.size); break;
            case "httpOnly": comparator = compareTo.bind(null, WebInspector.Cookie.prototype.httpOnly); break;
            case "secure": comparator = compareTo.bind(null, WebInspector.Cookie.prototype.secure); break;
            case "sameSite": comparator = compareTo.bind(null, WebInspector.Cookie.prototype.sameSite); break;
            default: compareTo.bind(null, WebInspector.Cookie.prototype.name);
        }

        cookies.sort(comparator);
    },

    /**
     * @param {!WebInspector.Cookie} cookie
     * @return {!WebInspector.DataGridNode}
     */
    _createGridNode: function(cookie)
    {
        var data = {};
        data.name = cookie.name();
        data.value = cookie.value();
        if (cookie.type() === WebInspector.Cookie.Type.Request) {
            data.domain = WebInspector.UIString("N/A");
            data.path = WebInspector.UIString("N/A");
            data.expires = WebInspector.UIString("N/A");
        } else {
            data.domain = cookie.domain() || "";
            data.path = cookie.path() || "";
            if (cookie.maxAge())
                data.expires = Number.secondsToString(parseInt(cookie.maxAge(), 10));
            else if (cookie.expires())
                data.expires = new Date(cookie.expires()).toISOString();
            else
                data.expires = WebInspector.UIString("Session");
        }
        data.size = cookie.size();
        const checkmark = "\u2713";
        data.httpOnly = (cookie.httpOnly() ? checkmark : "");
        data.secure = (cookie.secure() ? checkmark : "");
        data.sameSite = (cookie.sameSite() ? checkmark : "");

        var node = new WebInspector.DataGridNode(data);
        node.cookie = cookie;
        node.selectable = true;
        return node;
    },

    _onDeleteCookie: function(node)
    {
        var cookie = node.cookie;
        var neighbour = node.traverseNextNode() || node.traversePreviousNode();
        if (neighbour)
            this._nextSelectedCookie = neighbour.cookie;
        cookie.remove();
        this._refresh();
    },

    _refresh: function()
    {
        if (this._refreshCallback)
            this._refreshCallback();
    },

    __proto__: WebInspector.VBox.prototype
}
