/*
 * libjingle
 * Copyright 2011, Google Inc.
 *
 * 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.
 *  3. The name of the author may not be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
 */

#include <string>

#include "talk/app/webrtc/webrtcsdp.h"
#include "talk/base/gunit.h"
#include "talk/base/logging.h"
#include "talk/base/scoped_ptr.h"
#include "talk/base/stringutils.h"
#include "talk/p2p/base/constants.h"
#include "talk/session/phone/mediasession.h"

typedef std::vector<cricket::Candidate> Candidates;
using cricket::AudioCodec;
using cricket::AudioContentDescription;
using cricket::ContentInfo;
using cricket::CryptoParams;
using cricket::SessionDescription;
using cricket::StreamParams;
using cricket::VideoCodec;
using cricket::VideoContentDescription;

// Reference sdp string
static const char kSdpString[] =
    "v=0\r\n"
    "o=- 0 0 IN IP4 127.0.0.1\r\n"
    "s=\r\n"
    "t=0 0\r\n"
    "a=group:BUNDLE audio video\r\n"
    "m=audio 0 RTP/AVPF 103 104\r\n"
    "a=mid:audio\r\n"
    "a=rtcp-mux\r\n"
    "a=crypto:1 AES_CM_128_HMAC_SHA1_32 "
    "inline:NzB4d1BINUAvLEw6UzF3WSJ+PSdFcGdUJShpX1Zj|2^20|1:32 \r\n"
    "a=rtpmap:103 ISAC/16000\r\n"
    "a=rtpmap:104 ISAC/32000\r\n"
    "a=candidate:1 1 udp 1 127.0.0.1 1234 typ host name rtp network_name "
    "eth0 username user_rtp password password_rtp generation 0\r\n"
    "a=candidate:1 1 udp 1 127.0.0.1 1235 typ host name rtcp network_name "
    "eth0 username user_rtcp password password_rtcp generation 0\r\n"
    "a=ssrc:1 cname:stream_1_cname mslabel:local_stream_1 "
    "label:local_audio_1\r\n"
    "a=ssrc:4 cname:stream_2_cname mslabel:local_stream_2 "
    "label:local_audio_2\r\n"
    "m=video 0 RTP/AVPF 120\r\n"
    "a=mid:video\r\n"
    "a=crypto:1 AES_CM_128_HMAC_SHA1_80 "
    "inline:d0RmdmcmVCspeEc3QGZiNWpVLFJhQX1cfHAwJSoj|2^20|1:32 \r\n"
    "a=rtpmap:120 VP8/0\r\n"
    "a=candidate:1 1 udp 1 127.0.0.1 1236 typ host name video_rtcp "
    "network_name eth0 username user_video_rtcp password password_video_rtcp "
    "generation 0\r\n"
    "a=candidate:1 1 udp 1 127.0.0.1 1237 typ host name video_rtp "
    "network_name eth0 username user_video_rtp password password_video_rtp "
    "generation 0\r\n"
    "a=ssrc:2 cname:stream_1_cname mslabel:local_stream_1 "
    "label:local_video_1\r\n"
    "a=ssrc:3 cname:stream_1_cname mslabel:local_stream_1 "
    "label:local_video_2\r\n"
    "a=ssrc:5 cname:stream_2_cname mslabel:local_stream_2 "
    "label:local_video_3\r\n";

static const char kSdpDestroyer[] = "!@#$%^&";

// MediaStream 1
static const char kStreamLabel1[] = "local_stream_1";
static const char kStream1Cname[] = "stream_1_cname";
static const char kAudioTrackLabel1[] = "local_audio_1";
static const uint32 kAudioTrack1Ssrc = 1;
static const char kVideoTrackLabel1[] = "local_video_1";
static const uint32 kVideoTrack1Ssrc = 2;
static const char kVideoTrackLabel2[] = "local_video_2";
static const uint32 kVideoTrack2Ssrc = 3;

// MediaStream 2
static const char kStreamLabel2[] = "local_stream_2";
static const char kStream2Cname[] = "stream_2_cname";
static const char kAudioTrackLabel2[] = "local_audio_2";
static const uint32 kAudioTrack2Ssrc = 4;
static const char kVideoTrackLabel3[] = "local_video_3";
static const uint32 kVideoTrack3Ssrc = 5;

class WebRtcSdpTest : public testing::Test {
 public:
  WebRtcSdpTest() {
    // AudioContentDescription
    talk_base::scoped_ptr<AudioContentDescription> audio(
        new AudioContentDescription());
    audio->set_rtcp_mux(true);
    StreamParams audio_stream1;
    audio_stream1.name = kAudioTrackLabel1;
    audio_stream1.cname = kStream1Cname;
    audio_stream1.sync_label = kStreamLabel1;
    audio_stream1.ssrcs.push_back(kAudioTrack1Ssrc);
    audio->AddStream(audio_stream1);
    StreamParams audio_stream2;
    audio_stream2.name = kAudioTrackLabel2;
    audio_stream2.cname = kStream2Cname;
    audio_stream2.sync_label = kStreamLabel2;
    audio_stream2.ssrcs.push_back(kAudioTrack2Ssrc);
    audio->AddStream(audio_stream2);
    audio->AddCrypto(CryptoParams(1, "AES_CM_128_HMAC_SHA1_32",
        "inline:NzB4d1BINUAvLEw6UzF3WSJ+PSdFcGdUJShpX1Zj|2^20|1:32", ""));
    audio->AddCodec(AudioCodec(103, "ISAC", 16000, 0, 0, 0));
    audio->AddCodec(AudioCodec(104, "ISAC", 32000, 0, 0, 0));
    desc_.AddContent(cricket::CN_AUDIO, cricket::NS_JINGLE_RTP,
                     audio.release());

    // VideoContentDescription
    talk_base::scoped_ptr<VideoContentDescription> video(
        new VideoContentDescription());
    StreamParams video_stream1;
    video_stream1.name = kVideoTrackLabel1;
    video_stream1.cname = kStream1Cname;
    video_stream1.sync_label = kStreamLabel1;
    video_stream1.ssrcs.push_back(kVideoTrack1Ssrc);
    video->AddStream(video_stream1);
    StreamParams video_stream2;
    video_stream2.name = kVideoTrackLabel2;
    video_stream2.cname = kStream1Cname;
    video_stream2.sync_label = kStreamLabel1;
    video_stream2.ssrcs.push_back(kVideoTrack2Ssrc);
    video->AddStream(video_stream2);
    StreamParams video_stream3;
    video_stream3.name = kVideoTrackLabel3;
    video_stream3.cname = kStream2Cname;
    video_stream3.sync_label = kStreamLabel2;
    video_stream3.ssrcs.push_back(kVideoTrack3Ssrc);
    video->AddStream(video_stream3);
    video->AddCrypto(CryptoParams(1, "AES_CM_128_HMAC_SHA1_80",
        "inline:d0RmdmcmVCspeEc3QGZiNWpVLFJhQX1cfHAwJSoj|2^20|1:32", ""));
    video->AddCodec(VideoCodec(120, "VP8", 640, 480, 30, 0));
    desc_.AddContent(cricket::CN_VIDEO, cricket::NS_JINGLE_RTP,
                     video.release());

    int port = 1234;
    talk_base::SocketAddress address("127.0.0.1", port++);
    cricket::Candidate candidate1("rtp", "udp", address, 1,
        "user_rtp", "password_rtp", "local", "eth0", 0);
    address.SetPort(port++);
    cricket::Candidate candidate2("rtcp", "udp", address, 1,
        "user_rtcp", "password_rtcp", "local", "eth0", 0);
    address.SetPort(port++);
    cricket::Candidate candidate3("video_rtcp", "udp", address, 1,
        "user_video_rtcp", "password_video_rtcp", "local", "eth0", 0);
    address.SetPort(port++);
    cricket::Candidate candidate4("video_rtp", "udp", address, 1,
        "user_video_rtp", "password_video_rtp", "local", "eth0", 0);

    candidates_.push_back(candidate1);
    candidates_.push_back(candidate2);
    candidates_.push_back(candidate3);
    candidates_.push_back(candidate4);
  }

  bool CompareSessionDescription(const SessionDescription& desc1,
                                 const SessionDescription& desc2) {
    const ContentInfo* ac1 = desc1.GetContentByName("audio");
    const AudioContentDescription* acd1 =
        static_cast<const AudioContentDescription*>(ac1->description);
    const ContentInfo* vc1 = desc1.GetContentByName("video");
    const VideoContentDescription* vcd1 =
        static_cast<const VideoContentDescription*>(vc1->description);

    const ContentInfo* ac2 = desc2.GetContentByName("audio");
    const AudioContentDescription* acd2 =
        static_cast<const AudioContentDescription*>(ac2->description);
    const ContentInfo* vc2 = desc2.GetContentByName("video");
    const VideoContentDescription* vcd2 =
        static_cast<const VideoContentDescription*>(vc2->description);

    // rtcp_mux
    EXPECT_EQ(acd1->rtcp_mux(), acd2->rtcp_mux());
    EXPECT_EQ(vcd1->rtcp_mux(), vcd2->rtcp_mux());

    // cryptos
    EXPECT_EQ(acd1->cryptos().size(), acd2->cryptos().size());
    EXPECT_EQ(vcd1->cryptos().size(), vcd2->cryptos().size());
    for (size_t i = 0; i< acd1->cryptos().size(); ++i) {
      const CryptoParams c1 = acd1->cryptos().at(i);
      const CryptoParams c2 = acd2->cryptos().at(i);
      EXPECT_TRUE(c1.Matches(c2));
    }
    for (size_t i = 0; i< vcd1->cryptos().size(); ++i) {
      const CryptoParams c1 = vcd1->cryptos().at(i);
      const CryptoParams c2 = vcd2->cryptos().at(i);
      EXPECT_TRUE(c1.Matches(c2));
    }

    // codecs
    EXPECT_EQ(acd1->codecs().size(), acd2->codecs().size());
    EXPECT_EQ(vcd1->codecs().size(), vcd2->codecs().size());
    for (size_t i = 0; i< acd1->codecs().size(); ++i) {
      const AudioCodec c1 = acd1->codecs().at(i);
      const AudioCodec c2 = acd2->codecs().at(i);
      EXPECT_TRUE(c1.Matches(c2));
    }
    for (size_t i = 0; i< vcd1->codecs().size(); ++i) {
      const VideoCodec c1 = vcd1->codecs().at(i);
      const VideoCodec c2 = vcd2->codecs().at(i);
      EXPECT_TRUE(c1.Matches(c2));
      EXPECT_EQ(c1.width, c2.width);
      EXPECT_EQ(c1.height, c2.height);
      EXPECT_EQ(c1.framerate, c2.framerate);
    }

    // streams
    EXPECT_EQ(acd1->streams(), acd2->streams());
    EXPECT_EQ(vcd1->streams(), vcd2->streams());

    return true;
  }

  bool CompareCandidates(const Candidates& cs1, const Candidates& cs2) {
    EXPECT_EQ(cs1.size(), cs2.size());

    for (size_t i = 0; i< cs1.size(); ++i) {
      const cricket::Candidate c1 = cs1.at(i);
      const cricket::Candidate c2 = cs2.at(i);
      EXPECT_TRUE(c1.IsEquivalent(c2));
    }
    return true;
  }

  bool ReplaceAndTryToParse(const char* search, const char* replace) {
    SessionDescription desc;
    std::vector<cricket::Candidate> candidates;
    std::string sdp = kSdpString;
    talk_base::replace_substrs(search, strlen(search), replace,
        strlen(replace), &sdp);
    return webrtc::SdpDeserialize(sdp, &desc, &candidates);
  }

 protected:
  SessionDescription desc_;
  Candidates candidates_;
};

TEST_F(WebRtcSdpTest, Serialize) {
  std::string message = webrtc::SdpSerialize(desc_, candidates_);
  LOG(LS_INFO) << "SDP: " << message;
  EXPECT_EQ(std::string(kSdpString), message);
}

TEST_F(WebRtcSdpTest, Deserialize) {
  SessionDescription desc;
  std::vector<cricket::Candidate> candidates;
  // Deserialize
  EXPECT_TRUE(webrtc::SdpDeserialize(kSdpString, &desc, &candidates));
  // Verify
  LOG(LS_INFO) << "SDP: " << webrtc::SdpSerialize(desc, candidates);
  EXPECT_TRUE(CompareSessionDescription(desc_, desc));
  EXPECT_TRUE(CompareCandidates(candidates_, candidates));
}

TEST_F(WebRtcSdpTest, DeserializeBrokenSdp) {
  // Broken session description
  EXPECT_EQ(false, ReplaceAndTryToParse("v=", kSdpDestroyer));
  EXPECT_EQ(false, ReplaceAndTryToParse("o=", kSdpDestroyer));
  EXPECT_EQ(false, ReplaceAndTryToParse("s=", kSdpDestroyer));
  // Broken time description
  EXPECT_EQ(false, ReplaceAndTryToParse("t=", kSdpDestroyer));

  // No group line
  EXPECT_EQ(true, ReplaceAndTryToParse("a=group:BUNDLE audio video\r\n", ""));
  EXPECT_EQ(true, ReplaceAndTryToParse("a=mid:audio\r\n", ""));
  EXPECT_EQ(true, ReplaceAndTryToParse("a=mid:video\r\n", ""));

  // Broken media description
  EXPECT_EQ(true, ReplaceAndTryToParse("video 0 RTP/AVPF", kSdpDestroyer));
}
