/*
 * Copyright (C) 2011 Igalia S.L.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "config.h"
#include "WebKitBackForwardList.h"

#include "APIArray.h"
#include "WebKitBackForwardListPrivate.h"
#include <wtf/glib/GRefPtr.h>
#include <wtf/glib/WTFGType.h>

/**
 * SECTION: WebKitBackForwardList
 * @Short_description: List of visited pages
 * @Title: WebKitBackForwardList
 * @See_also: #WebKitWebView, #WebKitBackForwardListItem
 *
 * WebKitBackForwardList maintains a list of visited pages used to
 * navigate to recent pages. Items are inserted in the list in the
 * order they are visited.
 *
 * WebKitBackForwardList also maintains the notion of the current item
 * (which is always at index 0), the preceding item (which is at index -1),
 * and the following item (which is at index 1).
 * Methods webkit_web_view_go_back() and webkit_web_view_go_forward() move
 * the current item backward or forward by one. Method
 * webkit_web_view_go_to_back_forward_list_item() sets the current item to the
 * specified item. All other methods returning #WebKitBackForwardListItem<!-- -->s
 * do not change the value of the current item, they just return the requested
 * item or items.
 */

using namespace WebKit;

enum {
    CHANGED,

    LAST_SIGNAL
};

typedef HashMap<WebBackForwardListItem*, GRefPtr<WebKitBackForwardListItem> > BackForwardListItemsMap;

struct _WebKitBackForwardListPrivate {
    WebBackForwardList* backForwardItems;
    BackForwardListItemsMap itemsMap;
};

static guint signals[LAST_SIGNAL] = { 0, };

WEBKIT_DEFINE_TYPE(WebKitBackForwardList, webkit_back_forward_list, G_TYPE_OBJECT)

static void webkit_back_forward_list_class_init(WebKitBackForwardListClass* listClass)
{
    /**
     * WebKitBackForwardList::changed:
     * @back_forward_list: the #WebKitBackForwardList on which the signal was emitted
     * @item_added: (allow-none): the #WebKitBackForwardListItem added or %NULL
     * @items_removed: a #GList of #WebKitBackForwardListItem<!-- -->s
     *
     * This signal is emitted when @back_forward_list changes. This happens
     * when the current item is updated, a new item is added or one or more
     * items are removed. Note that both @item_added and @items_removed can
     * %NULL when only the current item is updated. Items are only removed
     * when the list is cleared or the maximum items limit is reached.
     */
    signals[CHANGED] = g_signal_new(
        "changed",
        G_TYPE_FROM_CLASS(listClass),
        G_SIGNAL_RUN_LAST,
        0, nullptr, nullptr,
        g_cclosure_marshal_generic,
        G_TYPE_NONE, 2,
        WEBKIT_TYPE_BACK_FORWARD_LIST_ITEM,
        G_TYPE_POINTER);
}

static WebKitBackForwardListItem* webkitBackForwardListGetOrCreateItem(WebKitBackForwardList* list, WebBackForwardListItem* webListItem)
{
    if (!webListItem)
        return 0;

    WebKitBackForwardListPrivate* priv = list->priv;
    GRefPtr<WebKitBackForwardListItem> listItem = priv->itemsMap.get(webListItem);
    if (listItem)
        return listItem.get();

    listItem = webkitBackForwardListItemGetOrCreate(webListItem);
    priv->itemsMap.set(webListItem, listItem);

    return listItem.get();
}

static GList* webkitBackForwardListCreateList(WebKitBackForwardList* list, API::Array* backForwardItems)
{
    if (!backForwardItems)
        return 0;

    GList* returnValue = 0;
    for (size_t i = 0; i < backForwardItems->size(); ++i) {
        WebBackForwardListItem* webItem = static_cast<WebBackForwardListItem*>(backForwardItems->at(i));
        returnValue = g_list_prepend(returnValue, webkitBackForwardListGetOrCreateItem(list, webItem));
    }

    return returnValue;
}

WebKitBackForwardList* webkitBackForwardListCreate(WebBackForwardList* backForwardItems)
{
    WebKitBackForwardList* list = WEBKIT_BACK_FORWARD_LIST(g_object_new(WEBKIT_TYPE_BACK_FORWARD_LIST, NULL));
    list->priv->backForwardItems = backForwardItems;

    return list;
}

void webkitBackForwardListChanged(WebKitBackForwardList* backForwardList, WebBackForwardListItem* webAddedItem, const Vector<Ref<WebBackForwardListItem>>& webRemovedItems)
{
    WebKitBackForwardListItem* addedItem = webkitBackForwardListGetOrCreateItem(backForwardList, webAddedItem);
    GList* removedItems = nullptr;

    WebKitBackForwardListPrivate* priv = backForwardList->priv;
    for (auto& webItem : webRemovedItems) {
        // After a session restore, we still don't have wrappers for the newly added items, so it would be possible that
        // the removed items are not in the map. In that case we create a wrapper now to pass it the changed signal, but
        // without adding it to the item map. See https://bugs.webkit.org/show_bug.cgi?id=153233.
        GRefPtr<WebKitBackForwardListItem> removedItem = priv->itemsMap.get(webItem.ptr());
        if (removedItem) {
            removedItems = g_list_prepend(removedItems, g_object_ref(removedItem.get()));
            priv->itemsMap.remove(webItem.ptr());
        } else
            removedItems = g_list_prepend(removedItems, webkitBackForwardListItemGetOrCreate(webItem.ptr()));
    }

    g_signal_emit(backForwardList, signals[CHANGED], 0, addedItem, removedItems, nullptr);
    g_list_free_full(removedItems, static_cast<GDestroyNotify>(g_object_unref));
}

/**
 * webkit_back_forward_list_get_current_item:
 * @back_forward_list: a #WebKitBackForwardList
 *
 * Returns the current item in @back_forward_list.
 *
 * Returns: (nullable) (transfer none): a #WebKitBackForwardListItem
 *    or %NULL if @back_forward_list is empty.
 */
WebKitBackForwardListItem* webkit_back_forward_list_get_current_item(WebKitBackForwardList* backForwardList)
{
    g_return_val_if_fail(WEBKIT_IS_BACK_FORWARD_LIST(backForwardList), 0);

    return webkitBackForwardListGetOrCreateItem(backForwardList, backForwardList->priv->backForwardItems->currentItem());
}

/**
 * webkit_back_forward_list_get_back_item:
 * @back_forward_list: a #WebKitBackForwardList
 *
 * Returns the item that precedes the current item.
 *
 * Returns: (nullable) (transfer none): the #WebKitBackForwardListItem
 *    preceding the current item or %NULL.
 */
WebKitBackForwardListItem* webkit_back_forward_list_get_back_item(WebKitBackForwardList* backForwardList)
{
    g_return_val_if_fail(WEBKIT_IS_BACK_FORWARD_LIST(backForwardList), 0);

    return webkitBackForwardListGetOrCreateItem(backForwardList, backForwardList->priv->backForwardItems->backItem());
}

/**
 * webkit_back_forward_list_get_forward_item:
 * @back_forward_list: a #WebKitBackForwardList
 *
 * Returns the item that follows the current item.
 *
 * Returns: (nullable) (transfer none): the #WebKitBackForwardListItem
 *    following the current item or %NULL.
 */
WebKitBackForwardListItem* webkit_back_forward_list_get_forward_item(WebKitBackForwardList* backForwardList)
{
    g_return_val_if_fail(WEBKIT_IS_BACK_FORWARD_LIST(backForwardList), 0);

    return webkitBackForwardListGetOrCreateItem(backForwardList, backForwardList->priv->backForwardItems->forwardItem());
}

/**
 * webkit_back_forward_list_get_nth_item:
 * @back_forward_list: a #WebKitBackForwardList
 * @index: the index of the item
 *
 * Returns the item at a given index relative to the current item.
 *
 * Returns: (nullable) (transfer none): the #WebKitBackForwardListItem
 *    located at the specified index relative to the current item or %NULL.
 */
WebKitBackForwardListItem* webkit_back_forward_list_get_nth_item(WebKitBackForwardList* backForwardList, gint index)
{
    g_return_val_if_fail(WEBKIT_IS_BACK_FORWARD_LIST(backForwardList), 0);

    return webkitBackForwardListGetOrCreateItem(backForwardList, backForwardList->priv->backForwardItems->itemAtIndex(index));
}

/**
 * webkit_back_forward_list_get_length:
 * @back_forward_list: a #WebKitBackForwardList
 *
 * Returns: the length of @back_forward_list.
 */
guint webkit_back_forward_list_get_length(WebKitBackForwardList* backForwardList)
{
    g_return_val_if_fail(WEBKIT_IS_BACK_FORWARD_LIST(backForwardList), 0);

    WebKitBackForwardListPrivate* priv = backForwardList->priv;
    guint currentItem = webkit_back_forward_list_get_current_item(backForwardList) ? 1 : 0;
    return priv->backForwardItems->backListCount() + priv->backForwardItems->forwardListCount() + currentItem;
}

/**
 * webkit_back_forward_list_get_back_list:
 * @back_forward_list: a #WebKitBackForwardList
 *
 * Returns: (element-type WebKit2.BackForwardListItem) (transfer container): a #GList of
 *    items preceding the current item.
 */
GList* webkit_back_forward_list_get_back_list(WebKitBackForwardList* backForwardList)
{
    g_return_val_if_fail(WEBKIT_IS_BACK_FORWARD_LIST(backForwardList), 0);

    return webkit_back_forward_list_get_back_list_with_limit(backForwardList, backForwardList->priv->backForwardItems->backListCount());
}

/**
 * webkit_back_forward_list_get_back_list_with_limit:
 * @back_forward_list: a #WebKitBackForwardList
 * @limit: the number of items to retrieve
 *
 * Returns: (element-type WebKit2.BackForwardListItem) (transfer container): a #GList of
 *    items preceding the current item limited by @limit.
 */
GList* webkit_back_forward_list_get_back_list_with_limit(WebKitBackForwardList* backForwardList, guint limit)
{
    g_return_val_if_fail(WEBKIT_IS_BACK_FORWARD_LIST(backForwardList), 0);

    WebKitBackForwardListPrivate* priv = backForwardList->priv;
    Ref<API::Array> apiArray = priv->backForwardItems->backListAsAPIArrayWithLimit(limit);
    return webkitBackForwardListCreateList(backForwardList, apiArray.ptr());
}

/**
 * webkit_back_forward_list_get_forward_list:
 * @back_forward_list: a #WebKitBackForwardList
 *
 * Returns: (element-type WebKit2.BackForwardListItem) (transfer container): a #GList of
 *    items following the current item.
 */
GList* webkit_back_forward_list_get_forward_list(WebKitBackForwardList* backForwardList)
{
    g_return_val_if_fail(WEBKIT_IS_BACK_FORWARD_LIST(backForwardList), 0);

    return webkit_back_forward_list_get_forward_list_with_limit(backForwardList, backForwardList->priv->backForwardItems->forwardListCount());
}

/**
 * webkit_back_forward_list_get_forward_list_with_limit:
 * @back_forward_list: a #WebKitBackForwardList
 * @limit: the number of items to retrieve
 *
 * Returns: (element-type WebKit2.BackForwardListItem) (transfer container): a #GList of
 *    items following the current item limited by @limit.
 */
GList* webkit_back_forward_list_get_forward_list_with_limit(WebKitBackForwardList* backForwardList, guint limit)
{
    g_return_val_if_fail(WEBKIT_IS_BACK_FORWARD_LIST(backForwardList), 0);

    WebKitBackForwardListPrivate* priv = backForwardList->priv;
    Ref<API::Array> apiArray = priv->backForwardItems->forwardListAsAPIArrayWithLimit(limit);
    return webkitBackForwardListCreateList(backForwardList, apiArray.ptr());
}
