/*
 * Copyright (C) 2016 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 "WebKitWebViewSessionState.h"

#include "WebKitWebViewSessionStatePrivate.h"
#include <wtf/glib/GRefPtr.h>
#include <wtf/glib/GUniquePtr.h>

using namespace WebKit;

struct _WebKitWebViewSessionState {
    _WebKitWebViewSessionState(SessionState&& state)
        : sessionState(WTFMove(state))
        , referenceCount(1)
    {
    }

    SessionState sessionState;
    int referenceCount;
};

G_DEFINE_BOXED_TYPE(WebKitWebViewSessionState, webkit_web_view_session_state, webkit_web_view_session_state_ref, webkit_web_view_session_state_unref)

static const guint16 g_sessionStateVersion = 1;
#define HTTP_BODY_ELEMENT_TYPE_STRING_V1 "(uaysxmxmds)"
#define HTTP_BODY_ELEMENT_FORMAT_STRING_V1 "(uay&sxmxmd&s)"
#define HTTP_BODY_TYPE_STRING_V1 "m(sa" HTTP_BODY_ELEMENT_TYPE_STRING_V1 ")"
#define HTTP_BODY_FORMAT_STRING_V1 "m(&sa" HTTP_BODY_ELEMENT_TYPE_STRING_V1 ")"
#define FRAME_STATE_TYPE_STRING_V1  "(ssssasmayxx(ii)d" HTTP_BODY_TYPE_STRING_V1 "av)"
#define FRAME_STATE_FORMAT_STRING_V1  "(&s&s&s&sasmayxx(ii)d@" HTTP_BODY_TYPE_STRING_V1 "av)"
#define BACK_FORWARD_LIST_ITEM_TYPE_STRING_V1  "(ts" FRAME_STATE_TYPE_STRING_V1 "u)"
#define BACK_FORWARD_LIST_ITEM_FORMAT_STRING_V1  "(t&s@" FRAME_STATE_TYPE_STRING_V1 "u)"
#define SESSION_STATE_TYPE_STRING_V1  "(qa" BACK_FORWARD_LIST_ITEM_TYPE_STRING_V1 "mu)"

// Use our own enum types to ensure the serialized format even if the core enums change.
enum ExternalURLsPolicy {
    Allow,
    AllowExternalSchemes,
    NotAllow
};

static inline unsigned toExternalURLsPolicy(WebCore::ShouldOpenExternalURLsPolicy policy)
{
    switch (policy) {
    case WebCore::ShouldOpenExternalURLsPolicy::ShouldAllow:
        return ExternalURLsPolicy::Allow;
    case WebCore::ShouldOpenExternalURLsPolicy::ShouldAllowExternalSchemes:
        return ExternalURLsPolicy::AllowExternalSchemes;
    case WebCore::ShouldOpenExternalURLsPolicy::ShouldNotAllow:
        return ExternalURLsPolicy::NotAllow;
    }

    return ExternalURLsPolicy::NotAllow;
}

static inline WebCore::ShouldOpenExternalURLsPolicy toWebCoreExternalURLsPolicy(unsigned policy)
{
    switch (policy) {
    case ExternalURLsPolicy::Allow:
        return WebCore::ShouldOpenExternalURLsPolicy::ShouldAllow;
    case ExternalURLsPolicy::AllowExternalSchemes:
        return WebCore::ShouldOpenExternalURLsPolicy::ShouldAllowExternalSchemes;
    case ExternalURLsPolicy::NotAllow:
        return WebCore::ShouldOpenExternalURLsPolicy::ShouldNotAllow;
    }

    return WebCore::ShouldOpenExternalURLsPolicy::ShouldNotAllow;
}

enum HTMLBodyElementType {
    Data,
    File,
    Blob
};

static inline unsigned toHTMLBodyElementType(HTTPBody::Element::Type type)
{
    switch (type) {
    case HTTPBody::Element::Type::Data:
        return HTMLBodyElementType::Data;
    case HTTPBody::Element::Type::File:
        return HTMLBodyElementType::File;
    case HTTPBody::Element::Type::Blob:
        return HTMLBodyElementType::Blob;
    }

    return HTMLBodyElementType::Data;
}

static inline HTTPBody::Element::Type toHTTPBodyElementType(unsigned type)
{
    switch (type) {
    case HTMLBodyElementType::Data:
        return HTTPBody::Element::Type::Data;
    case HTMLBodyElementType::File:
        return HTTPBody::Element::Type::File;
    case HTMLBodyElementType::Blob:
        return HTTPBody::Element::Type::Blob;
    }

    return HTTPBody::Element::Type::Data;
}

static inline void encodeHTTPBody(GVariantBuilder* sessionBuilder, const HTTPBody& httpBody)
{
    g_variant_builder_open(sessionBuilder, G_VARIANT_TYPE("(sa" HTTP_BODY_ELEMENT_TYPE_STRING_V1 ")"));
    g_variant_builder_add(sessionBuilder, "s", httpBody.contentType.utf8().data());
    g_variant_builder_open(sessionBuilder, G_VARIANT_TYPE("a" HTTP_BODY_ELEMENT_TYPE_STRING_V1));
    g_variant_builder_open(sessionBuilder, G_VARIANT_TYPE(HTTP_BODY_ELEMENT_TYPE_STRING_V1));
    for (const auto& element : httpBody.elements) {
        g_variant_builder_add(sessionBuilder, "u", toHTMLBodyElementType(element.type));
        g_variant_builder_open(sessionBuilder, G_VARIANT_TYPE("ay"));
        for (auto item : element.data)
            g_variant_builder_add(sessionBuilder, "y", item);
        g_variant_builder_close(sessionBuilder);
        g_variant_builder_add(sessionBuilder, "s", element.filePath.utf8().data());
        g_variant_builder_add(sessionBuilder, "x", element.fileStart);
        if (element.fileLength)
            g_variant_builder_add(sessionBuilder, "mx", TRUE, element.fileLength.value());
        else
            g_variant_builder_add(sessionBuilder, "mx", FALSE);
        if (element.expectedFileModificationTime)
            g_variant_builder_add(sessionBuilder, "md", TRUE, element.expectedFileModificationTime.value());
        else
            g_variant_builder_add(sessionBuilder, "md", FALSE);
        g_variant_builder_add(sessionBuilder, "s", element.blobURLString.utf8().data());
    }
    g_variant_builder_close(sessionBuilder);
    g_variant_builder_close(sessionBuilder);
    g_variant_builder_close(sessionBuilder);
}

static inline void encodeFrameState(GVariantBuilder* sessionBuilder, const FrameState& frameState)
{
    g_variant_builder_add(sessionBuilder, "s", frameState.urlString.utf8().data());
    g_variant_builder_add(sessionBuilder, "s", frameState.originalURLString.utf8().data());
    g_variant_builder_add(sessionBuilder, "s", frameState.referrer.utf8().data());
    g_variant_builder_add(sessionBuilder, "s", frameState.target.utf8().data());
    g_variant_builder_open(sessionBuilder, G_VARIANT_TYPE("as"));
    for (const auto& state : frameState.documentState)
        g_variant_builder_add(sessionBuilder, "s", state.utf8().data());
    g_variant_builder_close(sessionBuilder);
    if (!frameState.stateObjectData)
        g_variant_builder_add(sessionBuilder, "may", FALSE);
    else {
        g_variant_builder_open(sessionBuilder, G_VARIANT_TYPE("may"));
        g_variant_builder_open(sessionBuilder, G_VARIANT_TYPE("ay"));
        for (auto item : frameState.stateObjectData.value())
            g_variant_builder_add(sessionBuilder, "y", item);
        g_variant_builder_close(sessionBuilder);
        g_variant_builder_close(sessionBuilder);
    }
    g_variant_builder_add(sessionBuilder, "x", frameState.documentSequenceNumber);
    g_variant_builder_add(sessionBuilder, "x", frameState.itemSequenceNumber);
    g_variant_builder_add(sessionBuilder, "(ii)", frameState.scrollPosition.x(), frameState.scrollPosition.y());
    g_variant_builder_add(sessionBuilder, "d", frameState.pageScaleFactor);
    if (!frameState.httpBody)
        g_variant_builder_add(sessionBuilder, HTTP_BODY_TYPE_STRING_V1, FALSE);
    else {
        g_variant_builder_open(sessionBuilder, G_VARIANT_TYPE(HTTP_BODY_TYPE_STRING_V1));
        encodeHTTPBody(sessionBuilder, frameState.httpBody.value());
        g_variant_builder_close(sessionBuilder);
    }
    g_variant_builder_open(sessionBuilder, G_VARIANT_TYPE("av"));
    for (const auto& child : frameState.children) {
        GVariantBuilder frameStateBuilder;
        g_variant_builder_init(&frameStateBuilder, G_VARIANT_TYPE(FRAME_STATE_TYPE_STRING_V1));
        encodeFrameState(&frameStateBuilder, child);
        g_variant_builder_add(sessionBuilder, "v", g_variant_builder_end(&frameStateBuilder));
    }
    g_variant_builder_close(sessionBuilder);
}

static inline void encodePageState(GVariantBuilder* sessionBuilder, const PageState& pageState)
{
    g_variant_builder_add(sessionBuilder, "s", pageState.title.utf8().data());
    g_variant_builder_open(sessionBuilder, G_VARIANT_TYPE(FRAME_STATE_TYPE_STRING_V1));
    encodeFrameState(sessionBuilder, pageState.mainFrameState);
    g_variant_builder_close(sessionBuilder);
    g_variant_builder_add(sessionBuilder, "u", toExternalURLsPolicy(pageState.shouldOpenExternalURLsPolicy));
}

static inline void encodeBackForwardListItemState(GVariantBuilder* sessionBuilder, const BackForwardListItemState& item)
{
    g_variant_builder_open(sessionBuilder, G_VARIANT_TYPE(BACK_FORWARD_LIST_ITEM_TYPE_STRING_V1));
    g_variant_builder_add(sessionBuilder, "t", item.identifier);
    encodePageState(sessionBuilder, item.pageState);
    g_variant_builder_close(sessionBuilder);
}

static inline void encodeBackForwardListState(GVariantBuilder* sessionBuilder, const BackForwardListState& backForwardListState)
{
    g_variant_builder_open(sessionBuilder, G_VARIANT_TYPE("a" BACK_FORWARD_LIST_ITEM_TYPE_STRING_V1));
    for (const auto& item : backForwardListState.items)
        encodeBackForwardListItemState(sessionBuilder, item);
    g_variant_builder_close(sessionBuilder);

    if (backForwardListState.currentIndex)
        g_variant_builder_add(sessionBuilder, "mu", TRUE, backForwardListState.currentIndex.value());
    else
        g_variant_builder_add(sessionBuilder, "mu", FALSE);
}

static GBytes* encodeSessionState(const SessionState& sessionState)
{
    GVariantBuilder sessionBuilder;
    g_variant_builder_init(&sessionBuilder, G_VARIANT_TYPE(SESSION_STATE_TYPE_STRING_V1));
    g_variant_builder_add(&sessionBuilder, "q", g_sessionStateVersion);
    encodeBackForwardListState(&sessionBuilder, sessionState.backForwardListState);
    GRefPtr<GVariant> variant = g_variant_builder_end(&sessionBuilder);
    return g_variant_get_data_as_bytes(variant.get());
}

static inline bool decodeHTTPBody(GVariant* httpBodyVariant, HTTPBody& httpBody)
{
    gboolean hasHTTPBody;
    const char* contentType;
    GUniqueOutPtr<GVariantIter> elementsIter;
    g_variant_get(httpBodyVariant, HTTP_BODY_FORMAT_STRING_V1, &hasHTTPBody, &contentType, &elementsIter.outPtr());
    if (!hasHTTPBody)
        return false;
    httpBody.contentType = String::fromUTF8(contentType);
    gsize elementsLength = g_variant_iter_n_children(elementsIter.get());
    if (!elementsLength)
        return true;
    httpBody.elements.reserveInitialCapacity(elementsLength);
    unsigned type;
    GVariantIter* dataIter;
    const char* filePath;
    gint64 fileStart;
    gboolean hasFileLength;
    gint64 fileLength;
    gboolean hasFileModificationTime;
    gdouble fileModificationTime;
    const char* blobURLString;
    while (g_variant_iter_loop(elementsIter.get(), HTTP_BODY_ELEMENT_FORMAT_STRING_V1, &type, &dataIter, &filePath, &fileStart, &hasFileLength, &fileLength, &hasFileModificationTime, &fileModificationTime, &blobURLString)) {
        HTTPBody::Element element;
        element.type = toHTTPBodyElementType(type);
        if (gsize dataLength = g_variant_iter_n_children(dataIter)) {
            element.data.reserveInitialCapacity(dataLength);
            guchar dataValue;
            while (g_variant_iter_next(dataIter, "y", &dataValue))
                element.data.uncheckedAppend(dataValue);
        }
        element.filePath = String::fromUTF8(filePath);
        element.fileStart = fileStart;
        if (hasFileLength)
            element.fileLength = fileLength;
        if (hasFileModificationTime)
            element.expectedFileModificationTime = fileModificationTime;
        element.blobURLString = String::fromUTF8(blobURLString);

        httpBody.elements.uncheckedAppend(WTFMove(element));
    }

    return true;
}

static inline void decodeFrameState(GVariant* frameStateVariant, FrameState& frameState)
{
    const char* urlString;
    const char* originalURLString;
    const char* referrer;
    const char* target;
    GUniqueOutPtr<GVariantIter> documentStateIter;
    GUniqueOutPtr<GVariantIter> stateObjectDataIter;
    gint64 documentSequenceNumber;
    gint64 itemSequenceNumber;
    gint32 scrollPositionX, scrollPositionY;
    gdouble pageScaleFactor;
    GVariant* httpBodyVariant;
    GUniqueOutPtr<GVariantIter> childrenIter;
    g_variant_get(frameStateVariant, FRAME_STATE_FORMAT_STRING_V1, &urlString, &originalURLString, &referrer, &target,
        &documentStateIter.outPtr(), &stateObjectDataIter.outPtr(), &documentSequenceNumber, &itemSequenceNumber,
        &scrollPositionX, &scrollPositionY, &pageScaleFactor, &httpBodyVariant, &childrenIter.outPtr());
    frameState.urlString = String::fromUTF8(urlString);
    frameState.originalURLString = String::fromUTF8(originalURLString);
    // frameState.referrer must not be an empty string since we never want to
    // send an empty Referer header. Bug #159606.
    if (strlen(referrer))
        frameState.referrer = String::fromUTF8(referrer);
    frameState.target = String::fromUTF8(target);
    if (gsize documentStateLength = g_variant_iter_n_children(documentStateIter.get())) {
        frameState.documentState.reserveInitialCapacity(documentStateLength);
        const char* documentStateString;
        while (g_variant_iter_next(documentStateIter.get(), "&s", &documentStateString))
            frameState.documentState.uncheckedAppend(String::fromUTF8(documentStateString));
    }
    if (stateObjectDataIter) {
        Vector<uint8_t> stateObjectVector;
        if (gsize stateObjectDataLength = g_variant_iter_n_children(stateObjectDataIter.get())) {
            stateObjectVector.reserveInitialCapacity(stateObjectDataLength);
            guchar stateObjectDataValue;
            while (g_variant_iter_next(stateObjectDataIter.get(), "y", &stateObjectDataValue))
                stateObjectVector.uncheckedAppend(stateObjectDataValue);
        }
        frameState.stateObjectData = WTFMove(stateObjectVector);
    }
    frameState.documentSequenceNumber = documentSequenceNumber;
    frameState.itemSequenceNumber = itemSequenceNumber;
    frameState.scrollPosition.setX(scrollPositionX);
    frameState.scrollPosition.setY(scrollPositionY);
    frameState.pageScaleFactor = pageScaleFactor;
    HTTPBody httpBody;
    if (decodeHTTPBody(httpBodyVariant, httpBody))
        frameState.httpBody = WTFMove(httpBody);
    g_variant_unref(httpBodyVariant);
    while (GRefPtr<GVariant> child = adoptGRef(g_variant_iter_next_value(childrenIter.get()))) {
        FrameState childFrameState;
        GRefPtr<GVariant> childVariant = adoptGRef(g_variant_get_variant(child.get()));
        decodeFrameState(childVariant.get(), childFrameState);
        frameState.children.append(WTFMove(childFrameState));
    }
}

static inline void decodeBackForwardListItemState(GVariantIter* backForwardListStateIter, BackForwardListState& backForwardListState)
{
    gsize backForwardListStateLength = g_variant_iter_n_children(backForwardListStateIter);
    if (!backForwardListStateLength)
        return;

    backForwardListState.items.reserveInitialCapacity(backForwardListStateLength);
    guint64 identifier;
    const char* title;
    GVariant* frameStateVariant;
    unsigned shouldOpenExternalURLsPolicy;
    while (g_variant_iter_loop(backForwardListStateIter, BACK_FORWARD_LIST_ITEM_FORMAT_STRING_V1, &identifier, &title, &frameStateVariant, &shouldOpenExternalURLsPolicy)) {
        BackForwardListItemState state;
        state.identifier = identifier;
        state.pageState.title = String::fromUTF8(title);
        decodeFrameState(frameStateVariant, state.pageState.mainFrameState);
        state.pageState.shouldOpenExternalURLsPolicy = toWebCoreExternalURLsPolicy(shouldOpenExternalURLsPolicy);
        backForwardListState.items.uncheckedAppend(WTFMove(state));
    }
}

static bool decodeSessionState(GBytes* data, SessionState& sessionState)
{
    GRefPtr<GVariant> variant = g_variant_new_from_bytes(G_VARIANT_TYPE(SESSION_STATE_TYPE_STRING_V1), data, FALSE);
    if (!g_variant_is_normal_form(variant.get()))
        return false;

    guint16 version;
    GUniqueOutPtr<GVariantIter> backForwardListStateIter;
    gboolean hasCurrentIndex;
    guint32 currentIndex;
    g_variant_get(variant.get(), SESSION_STATE_TYPE_STRING_V1, &version, &backForwardListStateIter.outPtr(), &hasCurrentIndex, &currentIndex);
    if (!version || version > g_sessionStateVersion)
        return false;

    decodeBackForwardListItemState(backForwardListStateIter.get(), sessionState.backForwardListState);

    if (hasCurrentIndex)
        sessionState.backForwardListState.currentIndex = currentIndex;
    return true;
}

WebKitWebViewSessionState* webkitWebViewSessionStateCreate(SessionState&& sessionState)
{
    WebKitWebViewSessionState* state = static_cast<WebKitWebViewSessionState*>(fastMalloc(sizeof(WebKitWebViewSessionState)));
    new (state) WebKitWebViewSessionState(WTFMove(sessionState));
    return state;
}

const SessionState& webkitWebViewSessionStateGetSessionState(WebKitWebViewSessionState* state)
{
    return state->sessionState;
}

/**
 * webkit_web_view_session_state_new:
 * @data: a #GBytes
 *
 * Creates a new #WebKitWebViewSessionState from serialized data.
 *
 * Returns: (transfer full): a new #WebKitWebViewSessionState, or %NULL if @data doesn't contain a
 *     valid serialized #WebKitWebViewSessionState.
 *
 * Since: 2.12
 */
WebKitWebViewSessionState* webkit_web_view_session_state_new(GBytes* data)
{
    g_return_val_if_fail(data, nullptr);

    SessionState sessionState;
    if (!decodeSessionState(data, sessionState))
        return nullptr;
    return webkitWebViewSessionStateCreate(WTFMove(sessionState));
}

/**
 * webkit_web_view_session_state_ref:
 * @state: a #WebKitWebViewSessionState
 *
 * Atomically increments the reference count of @state by one. This
 * function is MT-safe and may be called from any thread.
 *
 * Returns: The passed in #WebKitWebViewSessionState
 *
 * Since: 2.12
 */
WebKitWebViewSessionState* webkit_web_view_session_state_ref(WebKitWebViewSessionState* state)
{
    g_return_val_if_fail(state, nullptr);
    g_atomic_int_inc(&state->referenceCount);
    return state;
}

/**
 * webkit_web_view_session_state_unref:
 * @state: a #WebKitWebViewSessionState
 *
 * Atomically decrements the reference count of @state by one. If the
 * reference count drops to 0, all memory allocated by the #WebKitWebViewSessionState is
 * released. This function is MT-safe and may be called from any thread.
 *
 * Since: 2.12
 */
void webkit_web_view_session_state_unref(WebKitWebViewSessionState* state)
{
    g_return_if_fail(state);
    if (g_atomic_int_dec_and_test(&state->referenceCount)) {
        state->~WebKitWebViewSessionState();
        fastFree(state);
    }
}

/**
 * webkit_web_view_session_state_serialize:
 * @state: a #WebKitWebViewSessionState
 *
 * Serializes a #WebKitWebViewSessionState.
 *
 * Returns: (transfer full): a #GBytes containing the @state serialized.
 *
 * Since: 2.12
 */
GBytes* webkit_web_view_session_state_serialize(WebKitWebViewSessionState* state)
{
    g_return_val_if_fail(state, nullptr);

    return encodeSessionState(state->sessionState);
}
