/*
 * Copyright (c) 2014, Ericsson AB. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice, this
 * list of conditions and the following disclaimer in the documentation and/or other
 * materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
 * OF SUCH DAMAGE.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "gstdtlssrtpdec.h"

#include "gstdtlsconnection.h"

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

static GstStaticPadTemplate rtp_src_template =
GST_STATIC_PAD_TEMPLATE ("rtp_src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("application/x-rtp")
    );

static GstStaticPadTemplate rtcp_src_template =
GST_STATIC_PAD_TEMPLATE ("rtcp_src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("application/x-rtcp")
    );

static GstStaticPadTemplate data_src_template =
GST_STATIC_PAD_TEMPLATE ("data_src",
    GST_PAD_SRC,
    GST_PAD_REQUEST,
    GST_STATIC_CAPS_ANY);

GST_DEBUG_CATEGORY_STATIC (gst_dtls_srtp_dec_debug);
#define GST_CAT_DEFAULT gst_dtls_srtp_dec_debug

#define gst_dtls_srtp_dec_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstDtlsSrtpDec, gst_dtls_srtp_dec,
    GST_TYPE_DTLS_SRTP_BIN, GST_DEBUG_CATEGORY_INIT (gst_dtls_srtp_dec_debug,
        "dtlssrtpdec", 0, "DTLS Decoder"));

enum
{
  PROP_0,
  PROP_PEM,
  PROP_PEER_PEM,
  NUM_PROPERTIES
};

static GParamSpec *properties[NUM_PROPERTIES];

#define DEFAULT_PEM NULL
#define DEFAULT_PEER_PEM NULL

static void gst_dtls_srtp_dec_set_property (GObject *, guint prop_id,
    const GValue *, GParamSpec *);
static void gst_dtls_srtp_dec_get_property (GObject *, guint prop_id,
    GValue *, GParamSpec *);

static GstPad *gst_dtls_srtp_dec_request_new_pad (GstElement *,
    GstPadTemplate *, const gchar * name, const GstCaps *);
static void gst_dtls_srtp_dec_release_pad (GstElement *, GstPad *);

static GstCaps *on_decoder_request_key (GstElement * srtp_decoder, guint ssrc,
    GstDtlsSrtpBin *);
static void on_peer_pem (GstElement * srtp_decoder, GParamSpec * pspec,
    GstDtlsSrtpDec * self);

static void gst_dtls_srtp_dec_remove_dtls_element (GstDtlsSrtpBin *);
static GstPadProbeReturn remove_dtls_decoder_probe_callback (GstPad *,
    GstPadProbeInfo *, GstElement *);

static void
gst_dtls_srtp_dec_class_init (GstDtlsSrtpDecClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *element_class;
  GstDtlsSrtpBinClass *dtls_srtp_bin_class;

  gobject_class = (GObjectClass *) klass;
  element_class = (GstElementClass *) klass;
  dtls_srtp_bin_class = (GstDtlsSrtpBinClass *) klass;

  gobject_class->set_property =
      GST_DEBUG_FUNCPTR (gst_dtls_srtp_dec_set_property);
  gobject_class->get_property =
      GST_DEBUG_FUNCPTR (gst_dtls_srtp_dec_get_property);

  element_class->request_new_pad =
      GST_DEBUG_FUNCPTR (gst_dtls_srtp_dec_request_new_pad);
  element_class->release_pad =
      GST_DEBUG_FUNCPTR (gst_dtls_srtp_dec_release_pad);

  dtls_srtp_bin_class->remove_dtls_element =
      GST_DEBUG_FUNCPTR (gst_dtls_srtp_dec_remove_dtls_element);

  properties[PROP_PEM] =
      g_param_spec_string ("pem",
      "PEM string",
      "A string containing a X509 certificate and RSA private key in PEM format",
      DEFAULT_PEM, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);

  properties[PROP_PEER_PEM] =
      g_param_spec_string ("peer-pem",
      "Peer PEM string",
      "The X509 certificate received in the DTLS handshake, in PEM format",
      DEFAULT_PEER_PEM, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);

  g_object_class_install_properties (gobject_class, NUM_PROPERTIES, properties);

  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&sink_template));
  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&rtp_src_template));
  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&rtcp_src_template));
  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&data_src_template));

  gst_element_class_set_static_metadata (element_class,
      "DTLS-SRTP Decoder",
      "Decoder/Network/DTLS/SRTP",
      "Decodes SRTP packets with a key received from DTLS",
      "Patrik Oldsberg patrik.oldsberg@ericsson.com");
}

static void
gst_dtls_srtp_dec_init (GstDtlsSrtpDec * self)
{
  GstElementClass *klass = GST_ELEMENT_GET_CLASS (GST_ELEMENT (self));
  GstPadTemplate *templ;
  GstPad *target_pad, *ghost_pad;
  gboolean ret;

/*
                                 +-----------+
            +--------------+  .-o|  dtlsdec  |o-R----data
            |          dtls|o-'  +-----------+
    sink---o|  dtlsdemux   |
            |       srt(c)p|o-.  +-----------+
            +--------------+  '-o|srtp    rtp|o------rtp
                                 |  srtpdec  |
                                o|srtcp  rtcp|o------rtcp
                                 +-----------+
*/

  self->srtp_dec = gst_element_factory_make ("srtpdec", "srtp-decoder");
  if (!self->srtp_dec) {
    GST_ERROR_OBJECT (self,
        "failed to create srtp_dec, is the srtp plugin registered?");
    return;
  }
  self->dtls_srtp_demux =
      gst_element_factory_make ("dtlssrtpdemux", "dtls-srtp-demux");
  if (!self->dtls_srtp_demux) {
    GST_ERROR_OBJECT (self, "failed to create dtls_srtp_demux");
    return;
  }
  self->bin.dtls_element = gst_element_factory_make ("dtlsdec", "dtls-decoder");
  if (!self->bin.dtls_element) {
    GST_ERROR_OBJECT (self, "failed to create dtls_dec");
    return;
  }

  gst_bin_add_many (GST_BIN (self),
      self->dtls_srtp_demux, self->bin.dtls_element, self->srtp_dec, NULL);

  ret =
      gst_element_link_pads (self->dtls_srtp_demux, "dtls_src",
      self->bin.dtls_element, NULL);
  g_return_if_fail (ret);
  ret =
      gst_element_link_pads (self->dtls_srtp_demux, "rtp_src", self->srtp_dec,
      "rtp_sink");
  g_return_if_fail (ret);

  templ = gst_element_class_get_pad_template (klass, "rtp_src");
  target_pad = gst_element_get_static_pad (self->srtp_dec, "rtp_src");
  ghost_pad = gst_ghost_pad_new_from_template ("rtp_src", target_pad, templ);
  gst_object_unref (target_pad);
  g_return_if_fail (ghost_pad);

  ret = gst_element_add_pad (GST_ELEMENT (self), ghost_pad);
  g_return_if_fail (ret);

  templ = gst_element_class_get_pad_template (klass, "rtcp_src");
  target_pad = gst_element_get_static_pad (self->srtp_dec, "rtcp_src");
  ghost_pad = gst_ghost_pad_new_from_template ("rtcp_src", target_pad, templ);
  gst_object_unref (target_pad);
  g_return_if_fail (ghost_pad);

  ret = gst_element_add_pad (GST_ELEMENT (self), ghost_pad);
  g_return_if_fail (ret);

  templ = gst_element_class_get_pad_template (klass, "sink");
  target_pad = gst_element_get_static_pad (self->dtls_srtp_demux, "sink");
  ghost_pad = gst_ghost_pad_new_from_template ("sink", target_pad, templ);
  gst_object_unref (target_pad);
  g_return_if_fail (ghost_pad);

  ret = gst_element_add_pad (GST_ELEMENT (self), ghost_pad);
  g_return_if_fail (ret);

  g_signal_connect (self->srtp_dec, "request-key",
      G_CALLBACK (on_decoder_request_key), self);
  g_signal_connect (self->bin.dtls_element, "notify::peer-pem",
      G_CALLBACK (on_peer_pem), self);
}

static void
gst_dtls_srtp_dec_set_property (GObject * object,
    guint prop_id, const GValue * value, GParamSpec * pspec)
{
  GstDtlsSrtpDec *self = GST_DTLS_SRTP_DEC (object);

  switch (prop_id) {
    case PROP_PEM:
      if (self->bin.dtls_element) {
        g_object_set_property (G_OBJECT (self->bin.dtls_element), "pem", value);
      } else {
        GST_WARNING_OBJECT (self, "tried to set pem after disabling DTLS");
      }
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (self, prop_id, pspec);
  }
}

static void
gst_dtls_srtp_dec_get_property (GObject * object,
    guint prop_id, GValue * value, GParamSpec * pspec)
{
  GstDtlsSrtpDec *self = GST_DTLS_SRTP_DEC (object);

  switch (prop_id) {
    case PROP_PEM:
      if (self->bin.dtls_element) {
        g_object_get_property (G_OBJECT (self->bin.dtls_element), "pem", value);
      } else {
        GST_WARNING_OBJECT (self, "tried to get pem after disabling DTLS");
      }
      break;
    case PROP_PEER_PEM:
      if (self->bin.dtls_element) {
        g_object_get_property (G_OBJECT (self->bin.dtls_element), "peer-pem",
            value);
      } else {
        GST_WARNING_OBJECT (self, "tried to get peer-pem after disabling DTLS");
      }
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (self, prop_id, pspec);
  }
}

static GstPad *
gst_dtls_srtp_dec_request_new_pad (GstElement * element,
    GstPadTemplate * templ, const gchar * name, const GstCaps * caps)
{
  GstDtlsSrtpDec *self = GST_DTLS_SRTP_DEC (element);
  GstElementClass *klass = GST_ELEMENT_GET_CLASS (element);
  GstPad *ghost_pad = NULL;
  gboolean ret;

  GST_DEBUG_OBJECT (element, "pad requested");

  g_return_val_if_fail (self->bin.dtls_element, NULL);
  g_return_val_if_fail (!self->bin.key_is_set, NULL);

  if (templ == gst_element_class_get_pad_template (klass, "data_src")) {
    GstPad *target_pad;

    target_pad = gst_element_get_request_pad (self->bin.dtls_element, "src");

    ghost_pad = gst_ghost_pad_new_from_template (name, target_pad, templ);
    gst_object_unref (target_pad);
    g_return_val_if_fail (ghost_pad, NULL);

    ret = gst_pad_set_active (ghost_pad, TRUE);
    g_return_val_if_fail (ret, NULL);
    ret = gst_element_add_pad (element, ghost_pad);
    g_return_val_if_fail (ret, NULL);

    GST_LOG_OBJECT (self, "added data src pad");

    if (caps) {
      g_object_set (ghost_pad, "caps", caps, NULL);
    }

    return ghost_pad;
  }

  g_return_val_if_reached (NULL);
}

static void
gst_dtls_srtp_dec_release_pad (GstElement * element, GstPad * pad)
{
  GstElementClass *klass = GST_ELEMENT_GET_CLASS (element);
  GstDtlsSrtpDec *self = GST_DTLS_SRTP_DEC (element);

  if (GST_PAD_PAD_TEMPLATE (pad) ==
      gst_element_class_get_pad_template (klass, "data_src")) {
    GstGhostPad *ghost_pad;
    GstPad *target_pad;

    ghost_pad = GST_GHOST_PAD (pad);
    target_pad = gst_ghost_pad_get_target (ghost_pad);

    if (target_pad != NULL) {
      gst_element_release_request_pad (self->bin.dtls_element, target_pad);

      gst_object_unref (target_pad);
      gst_ghost_pad_set_target (GST_GHOST_PAD (pad), NULL);
    }
  }

  gst_element_remove_pad (element, pad);
}

static GstCaps *
on_decoder_request_key (GstElement * srtp_decoder,
    guint ssrc, GstDtlsSrtpBin * bin)
{
  GstCaps *key_caps;
  GstBuffer *key_buffer = NULL;
  guint cipher;
  guint auth;

  if (bin->key_is_set) {
    if (bin->key) {
      if (bin->srtp_cipher && bin->srtp_auth && bin->srtcp_cipher
          && bin->srtcp_auth) {
        GST_DEBUG_OBJECT (bin, "setting srtp key");
        return gst_caps_new_simple ("application/x-srtp",
            "srtp-key", GST_TYPE_BUFFER, gst_buffer_copy (bin->key),
            "srtp-auth", G_TYPE_STRING, bin->srtp_auth,
            "srtcp-auth", G_TYPE_STRING, bin->srtcp_auth,
            "srtp-cipher", G_TYPE_STRING, bin->srtp_cipher,
            "srtcp-cipher", G_TYPE_STRING, bin->srtcp_cipher, NULL);
      } else {
        GST_WARNING_OBJECT (bin,
            "srtp key is set but not all ciphers and auths");
        return NULL;
      }
    }

    GST_DEBUG_OBJECT (bin, "setting srtp key to null");
    return gst_caps_new_simple ("application/x-srtp",
        "srtp-key", GST_TYPE_BUFFER, NULL,
        "srtp-auth", G_TYPE_STRING, "null",
        "srtcp-auth", G_TYPE_STRING, "null",
        "srtp-cipher", G_TYPE_STRING, "null",
        "srtcp-cipher", G_TYPE_STRING, "null", NULL);
  }

  if (bin->dtls_element) {
    g_object_get (bin->dtls_element, "decoder-key", &key_buffer, NULL);
  }

  if (key_buffer) {
    g_object_get (bin->dtls_element,
        "srtp-cipher", &cipher, "srtp-auth", &auth, NULL);

    g_return_val_if_fail (cipher == GST_DTLS_SRTP_CIPHER_AES_128_ICM, NULL);

    key_caps = gst_caps_new_simple ("application/x-srtp",
        "srtp-key", GST_TYPE_BUFFER, key_buffer,
        "srtp-cipher", G_TYPE_STRING, "aes-128-icm",
        "srtcp-cipher", G_TYPE_STRING, "aes-128-icm", NULL);

    switch (auth) {
      case GST_DTLS_SRTP_AUTH_HMAC_SHA1_32:
        gst_caps_set_simple (key_caps,
            "srtp-auth", G_TYPE_STRING, "hmac-sha1-32",
            "srtcp-auth", G_TYPE_STRING, "hmac-sha1-32", NULL);
        break;
      case GST_DTLS_SRTP_AUTH_HMAC_SHA1_80:
        gst_caps_set_simple (key_caps,
            "srtp-auth", G_TYPE_STRING, "hmac-sha1-80",
            "srtcp-auth", G_TYPE_STRING, "hmac-sha1-80", NULL);
        break;
      default:
        g_return_val_if_reached (NULL);
        break;
    }

    gst_buffer_unref (key_buffer);

    return key_caps;
  } else {
    GST_WARNING_OBJECT (bin, "no srtp key available yet");
  }

  return NULL;
}

static void
on_peer_pem (GstElement * srtp_decoder, GParamSpec * pspec,
    GstDtlsSrtpDec * self)
{
  g_return_if_fail (self);
  g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_PEER_PEM]);
}

static void
gst_dtls_srtp_dec_remove_dtls_element (GstDtlsSrtpBin * bin)
{
  GstDtlsSrtpDec *self = GST_DTLS_SRTP_DEC (bin);
  GstPad *demux_pad;
  gulong id;

  if (!bin->dtls_element) {
    return;
  }

  demux_pad = gst_element_get_static_pad (self->dtls_srtp_demux, "dtls_src");

  id = gst_pad_add_probe (demux_pad, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM,
      (GstPadProbeCallback) remove_dtls_decoder_probe_callback,
      bin->dtls_element, NULL);
  g_return_if_fail (id);
  bin->dtls_element = NULL;

  gst_pad_push_event (demux_pad,
      gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM,
          gst_structure_new_empty ("dummy")));

  gst_object_unref (demux_pad);
}

static GstPadProbeReturn
remove_dtls_decoder_probe_callback (GstPad * pad,
    GstPadProbeInfo * info, GstElement * element)
{
  gst_pad_remove_probe (pad, GST_PAD_PROBE_INFO_ID (info));

  gst_element_set_state (GST_ELEMENT (element), GST_STATE_NULL);
  gst_bin_remove (GST_BIN (GST_ELEMENT_PARENT (element)), element);

  return GST_PAD_PROBE_OK;
}
