/*
 * 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 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);

  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 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;
    }

    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;
}
