/*
 * 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/executablehelpers.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.
#ifdef ENABLE_WEBRTC
  rtc::Pathname path = rtc::GetExecutablePath();
  EXPECT_FALSE(path.empty());
  path.AppendPathname("../../talk/");
#else
  rtc::Pathname path = testing::GetTalkDirectory();
  EXPECT_FALSE(path.empty());  // must be run from inside "talk"
#endif
  path.AppendFolder("media/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
