/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "gstvideoconnector_p.h"
#include <unistd.h>

/* signals */
enum
{
  SIGNAL_RESEND_NEW_SEGMENT,
  SIGNAL_CONNECTION_FAILED,
  LAST_SIGNAL
};
static guint gst_video_connector_signals[LAST_SIGNAL] = { 0 };


GST_DEBUG_CATEGORY_STATIC (video_connector_debug);
#define GST_CAT_DEFAULT video_connector_debug

static GstStaticPadTemplate gst_video_connector_sink_factory =
GST_STATIC_PAD_TEMPLATE ("sink",
                         GST_PAD_SINK,
                         GST_PAD_ALWAYS,
                         GST_STATIC_CAPS_ANY);

static GstStaticPadTemplate gst_video_connector_src_factory =
GST_STATIC_PAD_TEMPLATE ("src",
                         GST_PAD_SRC,
                         GST_PAD_ALWAYS,
                         GST_STATIC_CAPS_ANY);

#define _do_init(bla) \
    GST_DEBUG_CATEGORY_INIT (video_connector_debug, \
    "video-connector", 0, "An identity like element for reconnecting video stream");

GST_BOILERPLATE_FULL (GstVideoConnector, gst_video_connector, GstElement,
                      GST_TYPE_ELEMENT, _do_init);

static void gst_video_connector_dispose (GObject * object);
static GstFlowReturn gst_video_connector_chain (GstPad * pad, GstBuffer * buf);
static GstFlowReturn gst_video_connector_buffer_alloc (GstPad * pad,
                                                       guint64 offset, guint size, GstCaps * caps, GstBuffer ** buf);
static GstStateChangeReturn gst_video_connector_change_state (GstElement *
                                                              element, GstStateChange transition);
static gboolean gst_video_connector_handle_sink_event (GstPad * pad,
                                                       GstEvent * event);
static gboolean gst_video_connector_new_buffer_probe(GstObject *pad, GstBuffer *buffer, guint * object);
static void gst_video_connector_resend_new_segment(GstElement * element, gboolean emitFailedSignal);
static gboolean gst_video_connector_setcaps (GstPad  *pad, GstCaps *caps);
static GstCaps *gst_video_connector_getcaps (GstPad * pad);
static gboolean gst_video_connector_acceptcaps (GstPad * pad, GstCaps * caps);

static void
gst_video_connector_base_init (gpointer g_class)
{
    GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);

    gst_element_class_set_details_simple (element_class, "Video Connector",
                                          "Generic",
                                          "An identity like element used for reconnecting video stream",
                                          "Dmytro Poplavskiy <dmytro.poplavskiy@nokia.com>");
    gst_element_class_add_pad_template (element_class,
                                        gst_static_pad_template_get (&gst_video_connector_sink_factory));
    gst_element_class_add_pad_template (element_class,
                                        gst_static_pad_template_get (&gst_video_connector_src_factory));
}

static void
gst_video_connector_class_init (GstVideoConnectorClass * klass)
{
    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
    GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);

    parent_class = g_type_class_peek_parent (klass);

    gobject_class->dispose = gst_video_connector_dispose;
    gstelement_class->change_state = gst_video_connector_change_state;
    klass->resend_new_segment = gst_video_connector_resend_new_segment;

    gst_video_connector_signals[SIGNAL_RESEND_NEW_SEGMENT] =
            g_signal_new ("resend-new-segment", G_TYPE_FROM_CLASS (klass),
                          G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                          G_STRUCT_OFFSET (GstVideoConnectorClass, resend_new_segment), NULL, NULL,
                          g_cclosure_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN);

    gst_video_connector_signals[SIGNAL_CONNECTION_FAILED] =
            g_signal_new ("connection-failed", G_TYPE_FROM_CLASS (klass),
                          G_SIGNAL_RUN_LAST,
                          0, NULL, NULL,
                          g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
}

static void
gst_video_connector_init (GstVideoConnector *element,
                          GstVideoConnectorClass *g_class)
{
    (void) g_class;
    element->sinkpad =
            gst_pad_new_from_static_template (&gst_video_connector_sink_factory,
                                              "sink");
    gst_pad_set_chain_function(element->sinkpad,
                               GST_DEBUG_FUNCPTR (gst_video_connector_chain));
    gst_pad_set_event_function(element->sinkpad,
                               GST_DEBUG_FUNCPTR (gst_video_connector_handle_sink_event));
    gst_pad_set_bufferalloc_function(element->sinkpad,
                                     GST_DEBUG_FUNCPTR (gst_video_connector_buffer_alloc));
    gst_pad_set_setcaps_function(element->sinkpad,
                               GST_DEBUG_FUNCPTR (gst_video_connector_setcaps));
    gst_pad_set_getcaps_function(element->sinkpad,
                               GST_DEBUG_FUNCPTR(gst_video_connector_getcaps));
    gst_pad_set_acceptcaps_function(element->sinkpad,
                               GST_DEBUG_FUNCPTR(gst_video_connector_acceptcaps));

    gst_element_add_pad (GST_ELEMENT (element), element->sinkpad);

    element->srcpad =
            gst_pad_new_from_static_template (&gst_video_connector_src_factory,
                                              "src");
    gst_pad_add_buffer_probe(element->srcpad,
                             G_CALLBACK(gst_video_connector_new_buffer_probe), element);
    gst_element_add_pad (GST_ELEMENT (element), element->srcpad);

    element->relinked = FALSE;
    element->failedSignalEmited = FALSE;
    gst_segment_init (&element->segment, GST_FORMAT_TIME);
    element->latest_buffer = NULL;
}

static void
gst_video_connector_reset (GstVideoConnector * element)
{
    element->relinked = FALSE;
    element->failedSignalEmited = FALSE;
    if (element->latest_buffer != NULL) {
        gst_buffer_unref (element->latest_buffer);
        element->latest_buffer = NULL;
    }
    gst_segment_init (&element->segment, GST_FORMAT_UNDEFINED);
}

static void
gst_video_connector_dispose (GObject * object)
{
    GstVideoConnector *element = GST_VIDEO_CONNECTOR (object);

    gst_video_connector_reset (element);

    G_OBJECT_CLASS (parent_class)->dispose (object);
}

// "When this function returns anything else than GST_FLOW_OK,
// the buffer allocation failed and buf does not contain valid data."
static GstFlowReturn
gst_video_connector_buffer_alloc (GstPad * pad, guint64 offset, guint size,
                                  GstCaps * caps, GstBuffer ** buf)
{
    GstVideoConnector *element;
    GstFlowReturn res = GST_FLOW_OK;
    element = GST_VIDEO_CONNECTOR (GST_PAD_PARENT (pad));

    if (!buf)
        return GST_FLOW_ERROR;
    *buf = NULL;

    gboolean isFailed = FALSE;
    while (1) {
        GST_OBJECT_LOCK (element);
        gst_object_ref(element->srcpad);
        GST_OBJECT_UNLOCK (element);

        // Check if downstream element is in NULL state
        // and wait for up to 1 second for it to switch.
        GstPad *peerPad = gst_pad_get_peer(element->srcpad);
        if (peerPad) {
            GstElement *parent = gst_pad_get_parent_element(peerPad);
            gst_object_unref (peerPad);
            if (parent) {
                GstState state;
                GstState pending;
                int totalTimeout = 0;
                // This seems to sleep for about 10ms usually.
                while (totalTimeout < 1000000) {
                    gst_element_get_state(parent, &state, &pending, 0);
                    if (state != GST_STATE_NULL)
                        break;
                    usleep(5000);
                    totalTimeout += 5000;
                }

                gst_object_unref (parent);
                if (state == GST_STATE_NULL) {
                    GST_DEBUG_OBJECT (element, "Downstream element is in NULL state");
                    // Downstream filter seems to be in the wrong state
                    return GST_FLOW_UNEXPECTED;
                }
            }
        }

        res = gst_pad_alloc_buffer(element->srcpad, offset, size, caps, buf);
        gst_object_unref (element->srcpad);

        GST_DEBUG_OBJECT (element, "buffer alloc finished: %s", gst_flow_get_name (res));

        if (res == GST_FLOW_WRONG_STATE) {
            // Just in case downstream filter is still somehow in the wrong state.
            // Pipeline stalls if we report GST_FLOW_WRONG_STATE.
            return GST_FLOW_UNEXPECTED;
        }

        if (res >= GST_FLOW_OK || isFailed == TRUE)
            break;

        //if gst_pad_alloc_buffer failed, emit "connection-failed" signal
        //so colorspace transformation element can be inserted
        GST_INFO_OBJECT(element, "gst_video_connector_buffer_alloc failed, emit connection-failed signal");
        g_signal_emit(G_OBJECT(element), gst_video_connector_signals[SIGNAL_CONNECTION_FAILED], 0);
        isFailed = TRUE;
    }

    return res;
}

static gboolean
gst_video_connector_setcaps (GstPad  *pad, GstCaps *caps)
{
    GstVideoConnector *element;
    element = GST_VIDEO_CONNECTOR (GST_PAD_PARENT (pad));

    /* forward-negotiate */
    gboolean res = gst_pad_set_caps(element->srcpad, caps);

    gchar * debugmsg = NULL;
    GST_DEBUG_OBJECT(element, "gst_video_connector_setcaps %s %i", debugmsg = gst_caps_to_string(caps), res);
    if (debugmsg)
        g_free(debugmsg);

    if (!res) {
        //if set_caps failed, emit "connection-failed" signal
        //so colorspace transformation element can be inserted
        GST_INFO_OBJECT(element, "gst_video_connector_setcaps failed, emit connection-failed signal");
        g_signal_emit(G_OBJECT(element), gst_video_connector_signals[SIGNAL_CONNECTION_FAILED], 0);

        return gst_pad_set_caps(element->srcpad, caps);
    }

    return TRUE;
}

static GstCaps *gst_video_connector_getcaps (GstPad * pad)
{
    GstVideoConnector *element;
    element = GST_VIDEO_CONNECTOR (GST_PAD_PARENT (pad));

#if (GST_VERSION_MICRO > 25)
    GstCaps *caps = gst_pad_peer_get_caps_reffed(element->srcpad);
#else
    GstCaps *caps = gst_pad_peer_get_caps(element->srcpad);
#endif

    if (!caps)
        caps = gst_caps_new_any();

    return caps;
}

static gboolean gst_video_connector_acceptcaps (GstPad * pad, GstCaps * caps)
{
    GstVideoConnector *element;
    element = GST_VIDEO_CONNECTOR (GST_PAD_PARENT (pad));

    return gst_pad_peer_accept_caps(element->srcpad, caps);
}

static void
gst_video_connector_resend_new_segment(GstElement * element, gboolean emitFailedSignal)
{
    GST_INFO_OBJECT(element, "New segment requested, failed signal enabled: %i", emitFailedSignal);
    GstVideoConnector *connector = GST_VIDEO_CONNECTOR(element);
    connector->relinked = TRUE;
    if (emitFailedSignal)
        connector->failedSignalEmited = FALSE;
}


static gboolean gst_video_connector_new_buffer_probe(GstObject *pad, GstBuffer *buffer, guint * object)
{
    (void) pad;
    (void) buffer;

    GstVideoConnector *element = GST_VIDEO_CONNECTOR (object);

    /*
      If relinking is requested, the current buffer should be rejected and
      the new segment + previous buffer should be pushed first
    */

    if (element->relinked)
        GST_LOG_OBJECT(element, "rejected buffer because of new segment request");

    return !element->relinked;
}


static GstFlowReturn
gst_video_connector_chain (GstPad * pad, GstBuffer * buf)
{
    GstFlowReturn res;
    GstVideoConnector *element;

    element = GST_VIDEO_CONNECTOR (gst_pad_get_parent (pad));

    do {
        /*
          Resend the segment message and last buffer to preroll the new sink.
          Sinks can be changed multiple times while paused,
          while loop allows to send the segment message and preroll
          all of them with the same buffer.
        */
        while (element->relinked) {
            element->relinked = FALSE;

            gint64 pos = element->segment.last_stop;

            if (element->latest_buffer && GST_BUFFER_TIMESTAMP_IS_VALID(element->latest_buffer)) {
                pos = GST_BUFFER_TIMESTAMP (element->latest_buffer);
            }

            //push a new segment and last buffer
            GstEvent *ev = gst_event_new_new_segment (TRUE,
                                                      element->segment.rate,
                                                      element->segment.format,
                                                      pos, //start
                                                      element->segment.stop,
                                                      pos);

            GST_DEBUG_OBJECT (element, "Pushing new segment event");
            if (!gst_pad_push_event (element->srcpad, ev)) {
                GST_WARNING_OBJECT (element,
                                    "Newsegment handling failed in %" GST_PTR_FORMAT,
                                    element->srcpad);
            }

            if (element->latest_buffer) {
                GST_DEBUG_OBJECT (element, "Pushing latest buffer...");
                gst_buffer_ref(element->latest_buffer);
                gst_pad_push(element->srcpad, element->latest_buffer);
            }
        }

        gst_buffer_ref(buf);

        //it's possible video sink is changed during gst_pad_push blocked by
        //pad lock, in this case ( element->relinked == TRUE )
        //the buffer should be rejected by the buffer probe and
        //the new segment + prev buffer should be sent before

        GST_LOG_OBJECT (element, "Pushing buffer...");
        res = gst_pad_push (element->srcpad, buf);
        GST_LOG_OBJECT (element, "Pushed buffer: %s", gst_flow_get_name (res));

        //if gst_pad_push failed give the service another chance,
        //it may still work with the colorspace element added
        if (!element->failedSignalEmited && res == GST_FLOW_NOT_NEGOTIATED) {
            element->failedSignalEmited = TRUE;
            GST_INFO_OBJECT(element, "gst_pad_push failed, emit connection-failed signal");
            g_signal_emit(G_OBJECT(element), gst_video_connector_signals[SIGNAL_CONNECTION_FAILED], 0);
        }

    } while (element->relinked);


    if (element->latest_buffer) {
        gst_buffer_unref (element->latest_buffer);
        element->latest_buffer = NULL;
    }

    element->latest_buffer = gst_buffer_ref(buf);

    gst_buffer_unref(buf);
    gst_object_unref (element);

    return res;
}

static GstStateChangeReturn
gst_video_connector_change_state (GstElement * element,
                                  GstStateChange transition)
{
    GstVideoConnector *connector;
    GstStateChangeReturn result;

    connector = GST_VIDEO_CONNECTOR(element);
    result = GST_ELEMENT_CLASS (parent_class)->change_state(element, transition);

    switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_READY:
        gst_video_connector_reset (connector);
        break;
    case GST_STATE_CHANGE_READY_TO_PAUSED:
        connector->relinked = FALSE;
        break;
    default:
        break;
    }

    return result;
}

static gboolean
gst_video_connector_handle_sink_event (GstPad * pad, GstEvent * event)
{
    if (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT) {
        GstVideoConnector *element = GST_VIDEO_CONNECTOR (gst_pad_get_parent (pad));

        gboolean update;
        GstFormat format;
        gdouble rate, arate;
        gint64 start, stop, time;

        gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
                                          &start, &stop, &time);

        GST_LOG_OBJECT (element,
                          "NEWSEGMENT update %d, rate %lf, applied rate %lf, "
                          "format %d, " "%" G_GINT64_FORMAT " -- %" G_GINT64_FORMAT ", time %"
                          G_GINT64_FORMAT, update, rate, arate, format, start, stop, time);

        gst_segment_set_newsegment_full (&element->segment, update,
                                         rate, arate, format, start, stop, time);

        gst_object_unref (element);
    }

    return gst_pad_event_default (pad, event);
}
