/*
 *  Copyright (C) 2015 Savoir-faire Linux Inc.
 *  Author: Stepan Salenikovich <stepan.salenikovich@savoirfairelinux.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program 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 General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
 *
 *  Additional permission under GNU GPL version 3 section 7:
 *
 *  If you modify this program, or any covered work, by linking or
 *  combining it with the OpenSSL project's OpenSSL library (or a
 *  modified version of that library), containing parts covered by the
 *  terms of the OpenSSL or SSLeay licenses, Savoir-faire Linux Inc.
 *  grants you additional permission to convey the resulting work.
 *  Corresponding Source for a non-source form of such a combination
 *  shall include the source code for the parts of OpenSSL used as well
 *  as that of the covered work.
 */

#include "ringnotify.h"
#include "config.h"

#if USE_LIBNOTIFY
#include <glib/gi18n.h>
#include <libnotify/notify.h>
#include <memory>
#include <globalinstances.h>
#include "native/pixbufmanipulator.h"
#include <call.h>
#include <QtCore/QSize>
#include <media/text.h>
#include <callmodel.h>
#endif

void
ring_notify_init()
{
#if USE_LIBNOTIFY
    notify_init("Ring");
#endif
}

void
ring_notify_uninit()
{
#if USE_LIBNOTIFY
    if (notify_is_initted())
        notify_uninit();
#endif
}

gboolean
ring_notify_is_initted()
{
#if USE_LIBNOTIFY
    return notify_is_initted();
#else
    return FALSE;
#endif
}

gboolean
ring_notify_incoming_call(
#if !USE_LIBNOTIFY
    G_GNUC_UNUSED
#endif
    Call* call)
{
    gboolean success = FALSE;
#if USE_LIBNOTIFY
    g_return_val_if_fail(call, FALSE);

    gchar *body = g_strdup_printf("%s", call->formattedName().toUtf8().constData());
    std::shared_ptr<NotifyNotification> notification(
        notify_notification_new(_("Incoming call"), body, NULL), g_object_unref);
    g_free(body);

    /* get photo */
    QVariant var_p = GlobalInstances::pixmapManipulator().callPhoto(
        call->peerContactMethod(), QSize(50, 50), false);
    std::shared_ptr<GdkPixbuf> photo = var_p.value<std::shared_ptr<GdkPixbuf>>();
    notify_notification_set_image_from_pixbuf(notification.get(), photo.get());

    /* calls have highest urgency */
    notify_notification_set_urgency(notification.get(), NOTIFY_URGENCY_CRITICAL);
    notify_notification_set_timeout(notification.get(), NOTIFY_EXPIRES_DEFAULT);

    GError *error = NULL;
    success = notify_notification_show(notification.get(), &error);

    if (success) {
        /* monitor the life cycle of the call and try to close the notification
         * once the call has been aswered */
        auto state_changed_conn = std::make_shared<QMetaObject::Connection>();
        *state_changed_conn = QObject::connect(
            call,
            &Call::lifeCycleStateChanged,
            [notification, state_changed_conn] (Call::LifeCycleState newState, G_GNUC_UNUSED Call::LifeCycleState previousState)
                {
                    g_return_if_fail(NOTIFY_IS_NOTIFICATION(notification.get()));
                    if (newState > Call::LifeCycleState::INITIALIZATION) {
                        /* note: not all systems will actually close the notification
                         * even if the above function returns as true */
                        if (!notify_notification_close(notification.get(), NULL))
                            g_warning("could not close notification");

                        /* once we (try to) close the notification, we can
                         * disconnect from this signal; this should also destroy
                         * the notification shared_ptr as its ref count will
                         * drop to 0 */
                        QObject::disconnect(*state_changed_conn);
                    }
                }
            );
    } else {
        g_warning("failed to show notification: %s", error->message);
        g_clear_error(&error);
    }
#endif
    return success;
}

#if USE_LIBNOTIFY

GHashTable *
ring_notify_get_chat_table()
{
    static std::unique_ptr<GHashTable, decltype(g_hash_table_destroy)&> chat_table(
        nullptr, g_hash_table_destroy);

    if (chat_table.get() == nullptr)
        chat_table.reset(g_hash_table_new_full(NULL, NULL, NULL, g_object_unref));

    return chat_table.get();
}

static void
notification_closed(NotifyNotification *notification, Call *call)
{
    g_return_if_fail(call);

    if (!g_hash_table_remove(ring_notify_get_chat_table(), call)) {
        g_warning("could not find notification associated with the given call");
        /* normally removing the notification from the hash table will unref it,
         * but if it was not found we should do it here */
        g_object_unref(notification);
    }
}

static gboolean
ring_notify_message_recieved(Call *call, const QMap<QString,QString>& msg)
{
    g_return_val_if_fail(call, FALSE);
    gboolean success = FALSE;

    GHashTable *chat_table = ring_notify_get_chat_table();

    gchar *title = g_strdup_printf(C_("Text message notification", "%s says:"), call->formattedName().toUtf8().constData());
    gchar *body = g_strdup_printf("%s", msg["text/plain"].toUtf8().constData());

    /* check if a notification already exists for this call */
    NotifyNotification *notification = (NotifyNotification *)g_hash_table_lookup(chat_table, call);
    if (notification) {
        /* update notification; append the new message to the old */
        GValue body_value = G_VALUE_INIT;
        g_value_init(&body_value, G_TYPE_STRING);
        g_object_get_property(G_OBJECT(notification), "body", &body_value);
        const gchar* body_old = g_value_get_string(&body_value);
        if (body_old && (strlen(body_old) > 0)) {
            gchar *body_new = g_strconcat(body_old, "\n", body, NULL);
            g_free(body);
            body = body_new;
        }
        notify_notification_update(notification, title, body, NULL);
    } else {
        /* create new notification object and associate it with the call in the
         * hash table; also store the pointer of the call in the notification
         * object so that it knows it's key in the hash table */
        notification = notify_notification_new(title, body, NULL);
        g_hash_table_insert(chat_table, call, notification);
        g_object_set_data(G_OBJECT(notification), "call", call);

        /* get photo */
        QVariant var_p = GlobalInstances::pixmapManipulator().callPhoto(
            call->peerContactMethod(), QSize(50, 50), false);
        std::shared_ptr<GdkPixbuf> photo = var_p.value<std::shared_ptr<GdkPixbuf>>();
        notify_notification_set_image_from_pixbuf(notification, photo.get());

        /* normal priority for messages */
        notify_notification_set_urgency(notification, NOTIFY_URGENCY_NORMAL);

        /* remove the key and value from the hash table once the notification is
         * closed; note that this will also unref the notification */
        g_signal_connect(notification, "closed", G_CALLBACK(notification_closed), call);
    }

    g_free(title);
    g_free(body);

    GError *error = NULL;
    success = notify_notification_show(notification, &error);
    if (!success) {
        g_warning("failed to show notification: %s", error->message);
        g_clear_error(&error);
        g_hash_table_remove(chat_table, call);
    }

    return success;
}

static void
ring_notify_call_messages(Call *call, Media::Text *media, RingClient *client)
{
    QObject::connect(
        media,
        &Media::Text::messageReceived,
        [call, client] (const QMap<QString,QString>& message) {
            g_return_if_fail(call && client);
            GtkWindow *main_window = ring_client_get_main_window(client);
            if ( main_window && gtk_window_is_active(main_window)) {
                /* only notify about messages not in the currently selected call */
                if (CallModel::instance().selectedCall() != call) {
                    ring_notify_message_recieved(call, message);
                }
            } else {
                /* send notifications for all messages if the window is not visibles*/
                ring_notify_message_recieved(call, message);
            }
        }
    );
}
#endif

void
ring_notify_monitor_chat_notifications(
#if !USE_LIBNOTIFY
    G_GNUC_UNUSED
#endif
    RingClient *client)
{
#if USE_LIBNOTIFY

    QObject::connect(
        &CallModel::instance(),
        &QAbstractItemModel::rowsInserted,
        [client] (const QModelIndex &parent, int first, int last)
        {
            g_return_if_fail(client);

            // don't add notifications for children of conferences
            // this also prevents a weird crash because the parent is determined as invalid when
            // calling CallModel::index(row, 0, parent)
            if (parent.isValid())
                return;

            for (int row = first; row <= last; ++row) {
                QModelIndex idx = CallModel::instance().index(row, 0, parent);
                auto call = CallModel::instance().getCall(idx);
                if (call) {

                    /* check if text media is already present */
                    if (call->hasMedia(Media::Media::Type::TEXT, Media::Media::Direction::IN)) {
                        Media::Text *media = call->firstMedia<Media::Text>(Media::Media::Direction::IN);
                        ring_notify_call_messages(call, media, client);
                    } else if (call->hasMedia(Media::Media::Type::TEXT, Media::Media::Direction::OUT)) {
                        Media::Text *media = call->firstMedia<Media::Text>(Media::Media::Direction::OUT);
                        ring_notify_call_messages(call, media, client);
                    } else {
                        /* monitor media for messaging text messaging */
                        QObject::connect(
                            call,
                            &Call::mediaAdded,
                            [call, client] (Media::Media* media) {
                                if (media->type() == Media::Media::Type::TEXT)
                                    ring_notify_call_messages(call, (Media::Text *)media, client);
                            }
                        );
                    }
                }
            }
        }
     );
#endif
 }

gboolean
ring_notify_close_chat_notification(
#if !USE_LIBNOTIFY
    G_GNUC_UNUSED
#endif
    Call *call)
{
    gboolean notification_existed = FALSE;

#if USE_LIBNOTIFY
    /* checks if there exists a chat notification associated with the given call
     * and tries to close it; if it did exist, then the function returns TRUE */
    g_return_val_if_fail(call, FALSE);


    GHashTable *chat_table = ring_notify_get_chat_table();

    NotifyNotification *notification = (NotifyNotification *)g_hash_table_lookup(chat_table, call);

    if (notification) {
        notification_existed = TRUE;

        GError *error = NULL;
        if (!notify_notification_close(notification, &error)) {
            g_warning("could not close notification: %s", error->message);
            g_clear_error(&error);

            /* closing should remove and free the notification from the hash table
             * since it failed to close, try to remove the notification from the
             * table manually */
            g_hash_table_remove(chat_table, call);
        }
    }
#endif

    return notification_existed;
}
