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

#include "DownloadProxy.h"
#include "WebKitDownloadPrivate.h"
#include "WebKitMarshal.h"
#include "WebKitURIRequestPrivate.h"
#include "WebKitURIResponsePrivate.h"
#include <WebCore/ErrorsGtk.h>
#include <WebCore/ResourceResponse.h>
#include <glib/gi18n-lib.h>
#include <wtf/gobject/GOwnPtr.h>
#include <wtf/gobject/GRefPtr.h>

using namespace WebKit;
using namespace WebCore;

enum {
    RECEIVED_DATA,
    FINISHED,
    FAILED,
    DECIDE_DESTINATION,
    CREATED_DESTINATION,

    LAST_SIGNAL
};

enum {
    PROP_0,

    PROP_DESTINATION,
    PROP_RESPONSE,
    PROP_ESTIMATED_PROGRESS
};

struct _WebKitDownloadPrivate {
    WKRetainPtr<WKDownloadRef> wkDownload;

    GRefPtr<WebKitURIRequest> request;
    GRefPtr<WebKitURIResponse> response;
    CString destinationURI;
    guint64 currentSize;
    bool isCancelled;
    GOwnPtr<GTimer> timer;
    gdouble lastProgress;
    gdouble lastElapsed;
};

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

G_DEFINE_TYPE(WebKitDownload, webkit_download, G_TYPE_OBJECT)

static void webkitDownloadFinalize(GObject* object)
{
    WEBKIT_DOWNLOAD(object)->priv->~WebKitDownloadPrivate();
    G_OBJECT_CLASS(webkit_download_parent_class)->finalize(object);
}

static void webkitDownloadGetProperty(GObject* object, guint propId, GValue* value, GParamSpec* paramSpec)
{
    WebKitDownload* download = WEBKIT_DOWNLOAD(object);

    switch (propId) {
    case PROP_DESTINATION:
        g_value_set_string(value, webkit_download_get_destination(download));
        break;
    case PROP_RESPONSE:
        g_value_set_object(value, webkit_download_get_response(download));
        break;
    case PROP_ESTIMATED_PROGRESS:
        g_value_set_double(value, webkit_download_get_estimated_progress(download));
        break;
    default:
        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec);
    }
}

static gboolean webkitDownloadDecideDestination(WebKitDownload* download, const gchar* suggestedFilename)
{
    if (!download->priv->destinationURI.isNull())
        return FALSE;

    GOwnPtr<char> filename(g_strdelimit(g_strdup(suggestedFilename), G_DIR_SEPARATOR_S, '_'));
    GOwnPtr<char> destination(g_build_filename(g_get_user_special_dir(G_USER_DIRECTORY_DOWNLOAD), filename.get(), NULL));
    GOwnPtr<char> destinationURI(g_filename_to_uri(destination.get(), 0, 0));
    download->priv->destinationURI = destinationURI.get();
    g_object_notify(G_OBJECT(download), "destination");
    return TRUE;
}

static void webkit_download_init(WebKitDownload* download)
{
    WebKitDownloadPrivate* priv = G_TYPE_INSTANCE_GET_PRIVATE(download, WEBKIT_TYPE_DOWNLOAD, WebKitDownloadPrivate);
    download->priv = priv;
    new (priv) WebKitDownloadPrivate();
}

static void webkit_download_class_init(WebKitDownloadClass* downloadClass)
{
    GObjectClass* objectClass = G_OBJECT_CLASS(downloadClass);
    objectClass->get_property = webkitDownloadGetProperty;
    objectClass->finalize = webkitDownloadFinalize;

    downloadClass->decide_destination = webkitDownloadDecideDestination;

    /**
     * WebKitDownload:destination:
     *
     * The local URI to where the download will be saved.
     */
    g_object_class_install_property(objectClass,
                                    PROP_DESTINATION,
                                    g_param_spec_string("destination",
                                                        _("Destination"),
                                                        _("The local URI to where the download will be saved"),
                                                        0,
                                                        WEBKIT_PARAM_READABLE));

    /**
     * WebKitDownload:response:
     *
     * The #WebKitURIResponse associated with this download.
     */
    g_object_class_install_property(objectClass,
                                    PROP_RESPONSE,
                                    g_param_spec_object("response",
                                                        _("Response"),
                                                        _("The response of the download"),
                                                        WEBKIT_TYPE_URI_RESPONSE,
                                                        WEBKIT_PARAM_READABLE));

    /**
     * WebKitDownload:estimated-progress:
     *
     * An estimate of the percent completion for the download operation.
     * This value will range from 0.0 to 1.0. The value is an estimate
     * based on the total number of bytes expected to be received for
     * a download.
     * If you need a more accurate progress information you can connect to
     * #WebKitDownload::received-data signal to track the progress.
     */
    g_object_class_install_property(objectClass,
                                    PROP_ESTIMATED_PROGRESS,
                                    g_param_spec_double("estimated-progress",
                                                        _("Estimated Progress"),
                                                        _("Determines the current progress of the download"),
                                                        0.0, 1.0, 1.0,
                                                        WEBKIT_PARAM_READABLE));

    /**
     * WebKitDownload::received-data:
     * @download: the #WebKitDownload
     * @data_length: the length of data received in bytes
     *
     * This signal is emitted after response is received,
     * every time new data has been written to the destination. It's
     * useful to know the progress of the download operation.
     */
    signals[RECEIVED_DATA] =
        g_signal_new("received-data",
                     G_TYPE_FROM_CLASS(objectClass),
                     G_SIGNAL_RUN_LAST,
                     0, 0, 0,
                     webkit_marshal_VOID__UINT64,
                     G_TYPE_NONE, 1,
                     G_TYPE_UINT64);

    /**
     * WebKitDownload::finished:
     * @download: the #WebKitDownload
     *
     * This signal is emitted when download finishes successfully or due to an error.
     * In case of errors #WebKitDownload::failed signal is emitted before this one.
     */
    signals[FINISHED] =
        g_signal_new("finished",
                     G_TYPE_FROM_CLASS(objectClass),
                     G_SIGNAL_RUN_LAST,
                     0, 0, 0,
                     g_cclosure_marshal_VOID__VOID,
                     G_TYPE_NONE, 0);

    /**
     * WebKitDownload::failed:
     * @download: the #WebKitDownload
     * @error: the #GError that was triggered
     *
     * This signal is emitted when an error occurs during the download
     * operation. The given @error, of the domain %WEBKIT_DOWNLOAD_ERROR,
     * contains further details of the failure. If the download is cancelled
     * with webkit_download_cancel(), this signal is emitted with error
     * %WEBKIT_DOWNLOAD_ERROR_CANCELLED_BY_USER. The download operation finishes
     * after an error and #WebKitDownload::finished signal is emitted after this one.
     */
    signals[FAILED] =
        g_signal_new("failed",
                     G_TYPE_FROM_CLASS(objectClass),
                     G_SIGNAL_RUN_LAST,
                     0, 0, 0,
                     g_cclosure_marshal_VOID__POINTER,
                     G_TYPE_NONE, 1,
                     G_TYPE_POINTER);

    /**
     * WebKitDownload::decide-destination:
     * @download: the #WebKitDownload
     * @suggested_filename: the filename suggested for the download
     *
     * This signal is emitted after response is received to
     * decide a destination URI for the download. If this signal is not
     * handled the file will be downloaded to %G_USER_DIRECTORY_DOWNLOAD
     * directory using @suggested_filename.
     *
     * Returns: %TRUE to stop other handlers from being invoked for the event.
     *   %FALSE to propagate the event further.
     */
    signals[DECIDE_DESTINATION] =
        g_signal_new("decide-destination",
                     G_TYPE_FROM_CLASS(objectClass),
                     G_SIGNAL_RUN_LAST,
                     G_STRUCT_OFFSET(WebKitDownloadClass, decide_destination),
                     g_signal_accumulator_true_handled, NULL,
                     webkit_marshal_BOOLEAN__STRING,
                     G_TYPE_BOOLEAN, 1,
                     G_TYPE_STRING);

    /**
     * WebKitDownload::created-destination:
     * @download: the #WebKitDownload
     * @destination: the destination URI
     *
     * This signal is emitted after #WebKitDownload::decide-destination and before
     * #WebKitDownload::received-data to notify that destination file has been
     * created successfully at @destination.
     */
    signals[CREATED_DESTINATION] =
        g_signal_new("created-destination",
                     G_TYPE_FROM_CLASS(objectClass),
                     G_SIGNAL_RUN_LAST,
                     0, 0, 0,
                     g_cclosure_marshal_VOID__STRING,
                     G_TYPE_BOOLEAN, 1,
                     G_TYPE_STRING);

    g_type_class_add_private(downloadClass, sizeof(WebKitDownloadPrivate));
}

WebKitDownload* webkitDownloadCreate(WKDownloadRef wkDownload)
{
    ASSERT(wkDownload);
    WebKitDownload* download = WEBKIT_DOWNLOAD(g_object_new(WEBKIT_TYPE_DOWNLOAD, NULL));
    download->priv->wkDownload = wkDownload;
    return download;
}

void webkitDownloadSetResponse(WebKitDownload* download, WebKitURIResponse* response)
{
    download->priv->response = response;
    g_object_notify(G_OBJECT(download), "response");
}

bool webkitDownloadIsCancelled(WebKitDownload* download)
{
    return download->priv->isCancelled;
}

void webkitDownloadNotifyProgress(WebKitDownload* download, guint64 bytesReceived)
{
    WebKitDownloadPrivate* priv = download->priv;
    if (priv->isCancelled)
        return;

    if (!download->priv->timer)
        download->priv->timer.set(g_timer_new());

    priv->currentSize += bytesReceived;
    g_signal_emit(download, signals[RECEIVED_DATA], 0, bytesReceived);

    // Throttle progress notification to not consume high amounts of
    // CPU on fast links, except when the last notification occured
    // more than 0.016 secs ago (60 FPS), or the last notified progress
    // is passed in 1% or we reached the end.
    gdouble currentElapsed = g_timer_elapsed(priv->timer.get(), 0);
    gdouble currentProgress = webkit_download_get_estimated_progress(download);

    if (priv->lastElapsed
        && priv->lastProgress
        && (currentElapsed - priv->lastElapsed) < 0.016
        && (currentProgress - priv->lastProgress) < 0.01
        && currentProgress < 1.0) {
        return;
    }
    priv->lastElapsed = currentElapsed;
    priv->lastProgress = currentProgress;
    g_object_notify(G_OBJECT(download), "estimated-progress");
}

void webkitDownloadFailed(WebKitDownload* download, const ResourceError& resourceError)
{
    GOwnPtr<GError> webError(g_error_new_literal(g_quark_from_string(resourceError.domain().utf8().data()),
                                                 resourceError.errorCode(),
                                                 resourceError.localizedDescription().utf8().data()));
    if (download->priv->timer)
        g_timer_stop(download->priv->timer.get());

    g_signal_emit(download, signals[FAILED], 0, webError.get());
    g_signal_emit(download, signals[FINISHED], 0, NULL);
}

void webkitDownloadCancelled(WebKitDownload* download)
{
    WebKitDownloadPrivate* priv = download->priv;
    webkitDownloadFailed(download, downloadCancelledByUserError(priv->response ? webkitURIResponseGetResourceResponse(priv->response.get()) : ResourceResponse()));
}

void webkitDownloadFinished(WebKitDownload* download)
{
    if (download->priv->isCancelled) {
        // Since cancellation is asynchronous, didFinish might be called even
        // if the download was cancelled. User cancelled the download,
        // so we should fail with cancelled error even if the download
        // actually finished successfully.
        webkitDownloadCancelled(download);
        return;
    }
    if (download->priv->timer)
        g_timer_stop(download->priv->timer.get());
    g_signal_emit(download, signals[FINISHED], 0, NULL);
}

CString webkitDownloadDecideDestinationWithSuggestedFilename(WebKitDownload* download, const CString& suggestedFilename)
{
    if (download->priv->isCancelled)
        return "";
    gboolean returnValue;
    g_signal_emit(download, signals[DECIDE_DESTINATION], 0, suggestedFilename.data(), &returnValue);
    return download->priv->destinationURI;
}

void webkitDownloadDestinationCreated(WebKitDownload* download, const CString& destinationURI)
{
    if (download->priv->isCancelled)
        return;
    gboolean returnValue;
    g_signal_emit(download, signals[CREATED_DESTINATION], 0, destinationURI.data(), &returnValue);
}

/**
 * webkit_download_get_request:
 * @download: a #WebKitDownload
 *
 * Retrieves the #WebKitURIRequest object that backs the download
 * process.
 *
 * Returns: (transfer none): the #WebKitURIRequest of @download
 */
WebKitURIRequest* webkit_download_get_request(WebKitDownload* download)
{
    g_return_val_if_fail(WEBKIT_IS_DOWNLOAD(download), 0);

    WebKitDownloadPrivate* priv = download->priv;
    if (!priv->request)
        priv->request = adoptGRef(webkitURIRequestCreateForResourceRequest(toImpl(priv->wkDownload.get())->request()));
    return download->priv->request.get();
}

/**
 * webkit_download_get_destination:
 * @download: a #WebKitDownload
 *
 * Obtains the URI to which the downloaded file will be written. You
 * can connect to #WebKitDownload::created-destination to make
 * sure this method returns a valid destination.
 *
 * Returns: the destination URI or %NULL
 */
const gchar* webkit_download_get_destination(WebKitDownload* download)
{
    g_return_val_if_fail(WEBKIT_IS_DOWNLOAD(download), 0);

    return download->priv->destinationURI.data();
}

/**
 * webkit_download_set_destination:
 * @download: a #WebKitDownload
 * @uri: the destination URI
 *
 * Sets the URI to which the downloaded file will be written.
 * This method should be called before the download transfer
 * starts or it will not have any effect on the ongoing download
 * operation. To set the destination using the filename suggested
 * by the server connect to #WebKitDownload::decide-destination
 * signal and call webkit_download_set_destination(). If you want to
 * set a fixed destination URI that doesn't depend on the suggested
 * filename you can connect to notify::response signal and call
 * webkit_download_set_destination().
 * If #WebKitDownload::decide-destination signal is not handled
 * and destination URI is not set when the download tranfer starts,
 * the file will be saved with the filename suggested by the server in
 * %G_USER_DIRECTORY_DOWNLOAD directory.
 */
void webkit_download_set_destination(WebKitDownload* download, const gchar* uri)
{
    g_return_if_fail(WEBKIT_IS_DOWNLOAD(download));
    g_return_if_fail(uri);

    WebKitDownloadPrivate* priv = download->priv;
    if (priv->destinationURI == uri)
        return;

    priv->destinationURI = uri;
    g_object_notify(G_OBJECT(download), "destination");
}

/**
 * webkit_download_get_response:
 * @download: a #WebKitDownload
 *
 * Retrieves the #WebKitURIResponse object that backs the download
 * process. This method returns %NULL if called before the response
 * is received from the server. You can connect to notify::response
 * signal to be notified when the response is received.
 *
 * Returns: (transfer none): the #WebKitURIResponse, or %NULL if
 *     the response hasn't been received yet.
 */
WebKitURIResponse* webkit_download_get_response(WebKitDownload* download)
{
    g_return_val_if_fail(WEBKIT_IS_DOWNLOAD(download), 0);

    return download->priv->response.get();
}

/**
 * webkit_download_cancel:
 * @download: a #WebKitDownload
 *
 * Cancels the download. When the ongoing download
 * operation is effectively cancelled the signal
 * #WebKitDownload::failed is emitted with
 * %WEBKIT_DOWNLOAD_ERROR_CANCELLED_BY_USER error.
 */
void webkit_download_cancel(WebKitDownload* download)
{
    g_return_if_fail(WEBKIT_IS_DOWNLOAD(download));

    download->priv->isCancelled = true;
    WKDownloadCancel(download->priv->wkDownload.get());
}

/**
 * webkit_download_get_estimated_progress:
 * @download: a #WebKitDownload
 *
 * Gets the value of the #WebKitDownload:estimated-progress property.
 * You can monitor the estimated progress of the download operation by
 * connecting to the notify::estimated-progress signal of @download.
 *
 * Returns: an estimate of the of the percent complete for a download
 *     as a range from 0.0 to 1.0.
 */
gdouble webkit_download_get_estimated_progress(WebKitDownload* download)
{
    g_return_val_if_fail(WEBKIT_IS_DOWNLOAD(download), 0);

    WebKitDownloadPrivate* priv = download->priv;
    if (!priv->response)
        return 0;

    guint64 contentLength = webkit_uri_response_get_content_length(priv->response.get());
    if (!contentLength)
        return 0;

    return static_cast<gdouble>(priv->currentSize) / static_cast<gdouble>(contentLength);
}

/**
 * webkit_download_get_elapsed_time:
 * @download: a #WebKitDownload
 *
 * Gets the elapsed time in seconds, including any fractional part.
 * If the download finished, had an error or was cancelled this is
 * the time between its start and the event.
 *
 * Returns: seconds since the download was started
 */
gdouble webkit_download_get_elapsed_time(WebKitDownload* download)
{
    g_return_val_if_fail(WEBKIT_IS_DOWNLOAD(download), 0);

    WebKitDownloadPrivate* priv = download->priv;
    if (!priv->timer)
        return 0;

    return g_timer_elapsed(priv->timer.get(), 0);
}

/**
 * webkit_download_get_received_data_length:
 * @download: a #WebKitDownload
 *
 * Gets the length of the data already downloaded for @download
 * in bytes.
 *
 * Returns: the amount of bytes already downloaded.
 */
guint64 webkit_download_get_received_data_length(WebKitDownload* download)
{
    g_return_val_if_fail(WEBKIT_IS_DOWNLOAD(download), 0);

    return download->priv->currentSize;
}
