/*
 * libjingle
 * Copyright 2004 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 "talk/media/base/testutils.h"

#include <math.h>

#include "talk/media/base/rtpdump.h"
#include "talk/media/base/videocapturer.h"
#include "talk/media/base/videoframe.h"
#include "webrtc/base/bytebuffer.h"
#include "webrtc/base/fileutils.h"
#include "webrtc/base/gunit.h"
#include "webrtc/base/pathutils.h"
#include "webrtc/base/stream.h"
#include "webrtc/base/stringutils.h"
#include "webrtc/base/testutils.h"

namespace cricket {

/////////////////////////////////////////////////////////////////////////
// Implementation of RawRtpPacket
/////////////////////////////////////////////////////////////////////////
void RawRtpPacket::WriteToByteBuffer(
    uint32 in_ssrc, rtc::ByteBuffer *buf) const {
  if (!buf) return;

  buf->WriteUInt8(ver_to_cc);
  buf->WriteUInt8(m_to_pt);
  buf->WriteUInt16(sequence_number);
  buf->WriteUInt32(timestamp);
  buf->WriteUInt32(in_ssrc);
  buf->WriteBytes(payload, sizeof(payload));
}

bool RawRtpPacket::ReadFromByteBuffer(rtc::ByteBuffer* buf) {
  if (!buf) return false;

  bool ret = true;
  ret &= buf->ReadUInt8(&ver_to_cc);
  ret &= buf->ReadUInt8(&m_to_pt);
  ret &= buf->ReadUInt16(&sequence_number);
  ret &= buf->ReadUInt32(&timestamp);
  ret &= buf->ReadUInt32(&ssrc);
  ret &= buf->ReadBytes(payload, sizeof(payload));
  return ret;
}

bool RawRtpPacket::SameExceptSeqNumTimestampSsrc(
    const RawRtpPacket& packet, uint16 seq, uint32 ts, uint32 ssc) const {
  return sequence_number == seq &&
      timestamp == ts &&
      ver_to_cc == packet.ver_to_cc &&
      m_to_pt == packet.m_to_pt &&
      ssrc == ssc &&
      0 == memcmp(payload, packet.payload, sizeof(payload));
}

/////////////////////////////////////////////////////////////////////////
// Implementation of RawRtcpPacket
/////////////////////////////////////////////////////////////////////////
void RawRtcpPacket::WriteToByteBuffer(rtc::ByteBuffer *buf) const {
  if (!buf) return;

  buf->WriteUInt8(ver_to_count);
  buf->WriteUInt8(type);
  buf->WriteUInt16(length);
  buf->WriteBytes(payload, sizeof(payload));
}

bool RawRtcpPacket::ReadFromByteBuffer(rtc::ByteBuffer* buf) {
  if (!buf) return false;

  bool ret = true;
  ret &= buf->ReadUInt8(&ver_to_count);
  ret &= buf->ReadUInt8(&type);
  ret &= buf->ReadUInt16(&length);
  ret &= buf->ReadBytes(payload, sizeof(payload));
  return ret;
}

bool RawRtcpPacket::EqualsTo(const RawRtcpPacket& packet) const {
  return ver_to_count == packet.ver_to_count &&
      type == packet.type &&
      length == packet.length &&
      0 == memcmp(payload, packet.payload, sizeof(payload));
}

/////////////////////////////////////////////////////////////////////////
// Implementation of class RtpTestUtility
/////////////////////////////////////////////////////////////////////////
const RawRtpPacket RtpTestUtility::kTestRawRtpPackets[] = {
    {0x80, 0, 0, 0,  RtpTestUtility::kDefaultSsrc, "RTP frame 0"},
    {0x80, 0, 1, 30, RtpTestUtility::kDefaultSsrc, "RTP frame 1"},
    {0x80, 0, 2, 30, RtpTestUtility::kDefaultSsrc, "RTP frame 1"},
    {0x80, 0, 3, 60, RtpTestUtility::kDefaultSsrc, "RTP frame 2"}
};
const RawRtcpPacket RtpTestUtility::kTestRawRtcpPackets[] = {
    // The Version is 2, the Length is 2, and the payload has 8 bytes.
    {0x80, 0, 2, "RTCP0000"},
    {0x80, 0, 2, "RTCP0001"},
    {0x80, 0, 2, "RTCP0002"},
    {0x80, 0, 2, "RTCP0003"},
};

size_t RtpTestUtility::GetTestPacketCount() {
  return rtc::_min(
      ARRAY_SIZE(kTestRawRtpPackets),
      ARRAY_SIZE(kTestRawRtcpPackets));
}

bool RtpTestUtility::WriteTestPackets(
    size_t count, bool rtcp, uint32 rtp_ssrc, RtpDumpWriter* writer) {
  if (!writer || count > GetTestPacketCount()) return false;

  bool result = true;
  uint32 elapsed_time_ms = 0;
  for (size_t i = 0; i < count && result; ++i) {
    rtc::ByteBuffer buf;
    if (rtcp) {
      kTestRawRtcpPackets[i].WriteToByteBuffer(&buf);
    } else {
      kTestRawRtpPackets[i].WriteToByteBuffer(rtp_ssrc, &buf);
    }

    RtpDumpPacket dump_packet(buf.Data(), buf.Length(), elapsed_time_ms, rtcp);
    elapsed_time_ms += kElapsedTimeInterval;
    result &= (rtc::SR_SUCCESS == writer->WritePacket(dump_packet));
  }
  return result;
}

bool RtpTestUtility::VerifyTestPacketsFromStream(
    size_t count, rtc::StreamInterface* stream, uint32 ssrc) {
  if (!stream) return false;

  uint32 prev_elapsed_time = 0;
  bool result = true;
  stream->Rewind();
  RtpDumpLoopReader reader(stream);
  for (size_t i = 0; i < count && result; ++i) {
    // Which loop and which index in the loop are we reading now.
    size_t loop = i / GetTestPacketCount();
    size_t index = i % GetTestPacketCount();

    RtpDumpPacket packet;
    result &= (rtc::SR_SUCCESS == reader.ReadPacket(&packet));
    // Check the elapsed time of the dump packet.
    result &= (packet.elapsed_time >= prev_elapsed_time);
    prev_elapsed_time = packet.elapsed_time;

    // Check the RTP or RTCP packet.
    rtc::ByteBuffer buf(reinterpret_cast<const char*>(&packet.data[0]),
                              packet.data.size());
    if (packet.is_rtcp()) {
      // RTCP packet.
      RawRtcpPacket rtcp_packet;
      result &= rtcp_packet.ReadFromByteBuffer(&buf);
      result &= rtcp_packet.EqualsTo(kTestRawRtcpPackets[index]);
    } else {
      // RTP packet.
      RawRtpPacket rtp_packet;
      result &= rtp_packet.ReadFromByteBuffer(&buf);
      result &= rtp_packet.SameExceptSeqNumTimestampSsrc(
          kTestRawRtpPackets[index],
          static_cast<uint16>(kTestRawRtpPackets[index].sequence_number +
                              loop * GetTestPacketCount()),
          static_cast<uint32>(kTestRawRtpPackets[index].timestamp +
                              loop * kRtpTimestampIncrease),
          ssrc);
    }
  }

  stream->Rewind();
  return result;
}

bool RtpTestUtility::VerifyPacket(const RtpDumpPacket* dump,
                                  const RawRtpPacket* raw,
                                  bool header_only) {
  if (!dump || !raw) return false;

  rtc::ByteBuffer buf;
  raw->WriteToByteBuffer(RtpTestUtility::kDefaultSsrc, &buf);

  if (header_only) {
    size_t header_len = 0;
    dump->GetRtpHeaderLen(&header_len);
    return header_len == dump->data.size() &&
        buf.Length() > dump->data.size() &&
        0 == memcmp(buf.Data(), &dump->data[0], dump->data.size());
  } else {
    return buf.Length() == dump->data.size() &&
        0 == memcmp(buf.Data(), &dump->data[0], dump->data.size());
  }
}

// Implementation of VideoCaptureListener.
VideoCapturerListener::VideoCapturerListener(VideoCapturer* capturer)
    : last_capture_state_(CS_STARTING),
      frame_count_(0),
      frame_fourcc_(0),
      frame_width_(0),
      frame_height_(0),
      frame_size_(0),
      resolution_changed_(false) {
  capturer->SignalStateChange.connect(this,
      &VideoCapturerListener::OnStateChange);
  capturer->SignalFrameCaptured.connect(this,
      &VideoCapturerListener::OnFrameCaptured);
}

void VideoCapturerListener::OnStateChange(VideoCapturer* capturer,
                                          CaptureState result) {
  last_capture_state_ = result;
}

void VideoCapturerListener::OnFrameCaptured(VideoCapturer* capturer,
                                            const CapturedFrame* frame) {
  ++frame_count_;
  if (1 == frame_count_) {
    frame_fourcc_ = frame->fourcc;
    frame_width_ = frame->width;
    frame_height_ = frame->height;
    frame_size_ = frame->data_size;
  } else if (frame_width_ != frame->width || frame_height_ != frame->height) {
    resolution_changed_ = true;
  }
}

// Returns the absolute path to a file in the testdata/ directory.
std::string GetTestFilePath(const std::string& filename) {
  // Locate test data directory.
  rtc::Pathname path = testing::GetTalkDirectory();
  EXPECT_FALSE(path.empty());  // must be run from inside "talk"
  path.AppendFolder("media");
  path.AppendFolder("testdata");
  path.SetFilename(filename);
  return path.pathname();
}

// Loads the image with the specified prefix and size into |out|.
bool LoadPlanarYuvTestImage(const std::string& prefix,
                            int width, int height, uint8* out) {
  std::stringstream ss;
  ss << prefix << "." << width << "x" << height << "_P420.yuv";

  rtc::scoped_ptr<rtc::FileStream> stream(
      rtc::Filesystem::OpenFile(rtc::Pathname(
          GetTestFilePath(ss.str())), "rb"));
  if (!stream) {
    return false;
  }

  rtc::StreamResult res =
      stream->ReadAll(out, I420_SIZE(width, height), NULL, NULL);
  return (res == rtc::SR_SUCCESS);
}

// Dumps the YUV image out to a file, for visual inspection.
// PYUV tool can be used to view dump files.
void DumpPlanarYuvTestImage(const std::string& prefix, const uint8* img,
                            int w, int h) {
  rtc::FileStream fs;
  char filename[256];
  rtc::sprintfn(filename, sizeof(filename), "%s.%dx%d_P420.yuv",
                      prefix.c_str(), w, h);
  fs.Open(filename, "wb", NULL);
  fs.Write(img, I420_SIZE(w, h), NULL, NULL);
}

// Dumps the ARGB image out to a file, for visual inspection.
// ffplay tool can be used to view dump files.
void DumpPlanarArgbTestImage(const std::string& prefix, const uint8* img,
                             int w, int h) {
  rtc::FileStream fs;
  char filename[256];
  rtc::sprintfn(filename, sizeof(filename), "%s.%dx%d_ARGB.raw",
                      prefix.c_str(), w, h);
  fs.Open(filename, "wb", NULL);
  fs.Write(img, ARGB_SIZE(w, h), NULL, NULL);
}

bool VideoFrameEqual(const VideoFrame* frame0, const VideoFrame* frame1) {
  const uint8* y0 = frame0->GetYPlane();
  const uint8* u0 = frame0->GetUPlane();
  const uint8* v0 = frame0->GetVPlane();
  const uint8* y1 = frame1->GetYPlane();
  const uint8* u1 = frame1->GetUPlane();
  const uint8* v1 = frame1->GetVPlane();

  for (size_t i = 0; i < frame0->GetHeight(); ++i) {
    if (0 != memcmp(y0, y1, frame0->GetWidth())) {
      return false;
    }
    y0 += frame0->GetYPitch();
    y1 += frame1->GetYPitch();
  }

  for (size_t i = 0; i < frame0->GetChromaHeight(); ++i) {
    if (0 != memcmp(u0, u1, frame0->GetChromaWidth())) {
      return false;
    }
    if (0 != memcmp(v0, v1, frame0->GetChromaWidth())) {
      return false;
    }
    u0 += frame0->GetUPitch();
    v0 += frame0->GetVPitch();
    u1 += frame1->GetUPitch();
    v1 += frame1->GetVPitch();
  }

  return true;
}

cricket::StreamParams CreateSimStreamParams(
    const std::string& cname, const std::vector<uint32>& ssrcs) {
  cricket::StreamParams sp;
  cricket::SsrcGroup sg(cricket::kSimSsrcGroupSemantics, ssrcs);
  sp.ssrcs = ssrcs;
  sp.ssrc_groups.push_back(sg);
  sp.cname = cname;
  return sp;
}

// There should be an rtx_ssrc per ssrc.
cricket::StreamParams CreateSimWithRtxStreamParams(
    const std::string& cname, const std::vector<uint32>& ssrcs,
    const std::vector<uint32>& rtx_ssrcs) {
  cricket::StreamParams sp = CreateSimStreamParams(cname, ssrcs);
  for (size_t i = 0; i < ssrcs.size(); ++i) {
    sp.ssrcs.push_back(rtx_ssrcs[i]);
    std::vector<uint32> fid_ssrcs;
    fid_ssrcs.push_back(ssrcs[i]);
    fid_ssrcs.push_back(rtx_ssrcs[i]);
    cricket::SsrcGroup fid_group(cricket::kFidSsrcGroupSemantics, fid_ssrcs);
    sp.ssrc_groups.push_back(fid_group);
  }
  return sp;
}

}  // namespace cricket
