/*
 * 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_static_pad_template (element_class, &sink_template);
  gst_element_class_add_static_pad_template (element_class, &rtp_src_template);
  gst_element_class_add_static_pad_template (element_class, &rtcp_src_template);
  gst_element_class_add_static_pad_template (element_class, &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", NULL);
  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", NULL);
  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", NULL);
  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;
}
