/*
 * 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 <stdio.h>

#include <string>
#include <vector>

#include "talk/media/base/testutils.h"
#include "talk/media/devices/filevideocapturer.h"
#include "webrtc/base/gunit.h"
#include "webrtc/base/logging.h"
#include "webrtc/base/thread.h"

namespace {

class FileVideoCapturerTest : public testing::Test {
 public:
  virtual void SetUp() {
    capturer_.reset(new cricket::FileVideoCapturer);
  }

  bool OpenFile(const std::string& filename) {
    return capturer_->Init(cricket::GetTestFilePath(filename));
  }

 protected:
  class VideoCapturerListener : public sigslot::has_slots<> {
   public:
    VideoCapturerListener()
        : frame_count_(0),
          frame_width_(0),
          frame_height_(0),
          resolution_changed_(false) {
    }

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

    int frame_count() const { return frame_count_; }
    int frame_width() const { return frame_width_; }
    int frame_height() const { return frame_height_; }
    bool resolution_changed() const { return resolution_changed_; }

   private:
    int frame_count_;
    int frame_width_;
    int frame_height_;
    bool resolution_changed_;
  };

  rtc::scoped_ptr<cricket::FileVideoCapturer> capturer_;
  cricket::VideoFormat capture_format_;
};

TEST_F(FileVideoCapturerTest, TestNotOpened) {
  EXPECT_EQ("", capturer_->GetId());
  EXPECT_TRUE(capturer_->GetSupportedFormats()->empty());
  EXPECT_EQ(NULL, capturer_->GetCaptureFormat());
  EXPECT_FALSE(capturer_->IsRunning());
}

TEST_F(FileVideoCapturerTest, TestInvalidOpen) {
  EXPECT_FALSE(OpenFile("NotmeNotme"));
}

TEST_F(FileVideoCapturerTest, TestOpen) {
  EXPECT_TRUE(OpenFile("captured-320x240-2s-48.frames"));
  EXPECT_NE("", capturer_->GetId());
  EXPECT_TRUE(NULL != capturer_->GetSupportedFormats());
  EXPECT_EQ(1U, capturer_->GetSupportedFormats()->size());
  EXPECT_EQ(NULL, capturer_->GetCaptureFormat());  // not started yet
  EXPECT_FALSE(capturer_->IsRunning());
}

TEST_F(FileVideoCapturerTest, TestLargeSmallDesiredFormat) {
  EXPECT_TRUE(OpenFile("captured-320x240-2s-48.frames"));
  // desired format with large resolution.
  cricket::VideoFormat desired(
      3200, 2400, cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_ANY);
  EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &capture_format_));
  EXPECT_EQ(320, capture_format_.width);
  EXPECT_EQ(240, capture_format_.height);

  // Desired format with small resolution.
  desired.width = 0;
  desired.height = 0;
  EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &capture_format_));
  EXPECT_EQ(320, capture_format_.width);
  EXPECT_EQ(240, capture_format_.height);
}

TEST_F(FileVideoCapturerTest, TestSupportedAsDesiredFormat) {
  EXPECT_TRUE(OpenFile("captured-320x240-2s-48.frames"));
  // desired format same as the capture format supported by the file
  cricket::VideoFormat desired = capturer_->GetSupportedFormats()->at(0);
  EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &capture_format_));
  EXPECT_TRUE(desired == capture_format_);

  // desired format same as the supported capture format except the fourcc
  desired.fourcc = cricket::FOURCC_ANY;
  EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &capture_format_));
  EXPECT_NE(capture_format_.fourcc, desired.fourcc);

  // desired format with minimum interval
  desired.interval = cricket::VideoFormat::kMinimumInterval;
  EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &capture_format_));
}

TEST_F(FileVideoCapturerTest, TestNoRepeat) {
  EXPECT_TRUE(OpenFile("captured-320x240-2s-48.frames"));
  VideoCapturerListener listener;
  capturer_->SignalFrameCaptured.connect(
      &listener, &VideoCapturerListener::OnFrameCaptured);
  capturer_->set_repeat(0);
  capture_format_ = capturer_->GetSupportedFormats()->at(0);
  EXPECT_EQ(cricket::CS_RUNNING, capturer_->Start(capture_format_));
  EXPECT_TRUE_WAIT(!capturer_->IsRunning(), 20000);
  EXPECT_EQ(48, listener.frame_count());
}

TEST_F(FileVideoCapturerTest, TestRepeatForever) {
  // Start the capturer_ with 50 fps and read no less than 150 frames.
  EXPECT_TRUE(OpenFile("captured-320x240-2s-48.frames"));
  VideoCapturerListener listener;
  capturer_->SignalFrameCaptured.connect(
      &listener, &VideoCapturerListener::OnFrameCaptured);
  capturer_->set_repeat(cricket::FileVideoCapturer::kForever);
  capture_format_ = capturer_->GetSupportedFormats()->at(0);
  capture_format_.interval = cricket::VideoFormat::FpsToInterval(50);
  EXPECT_EQ(cricket::CS_RUNNING, capturer_->Start(capture_format_));
  EXPECT_TRUE(NULL != capturer_->GetCaptureFormat());
  EXPECT_TRUE(capture_format_ == *capturer_->GetCaptureFormat());
  EXPECT_TRUE_WAIT(!capturer_->IsRunning() ||
                   listener.frame_count() >= 150, 20000);
  capturer_->Stop();
  EXPECT_FALSE(capturer_->IsRunning());
  EXPECT_GE(listener.frame_count(), 150);
  EXPECT_FALSE(listener.resolution_changed());
  EXPECT_EQ(listener.frame_width(), capture_format_.width);
  EXPECT_EQ(listener.frame_height(), capture_format_.height);
}

// See: https://code.google.com/p/webrtc/issues/detail?id=2409
TEST_F(FileVideoCapturerTest, DISABLED_TestPartialFrameHeader) {
  EXPECT_TRUE(OpenFile("1.frame_plus_1.byte"));
  VideoCapturerListener listener;
  capturer_->SignalFrameCaptured.connect(
      &listener, &VideoCapturerListener::OnFrameCaptured);
  capturer_->set_repeat(0);
  capture_format_ = capturer_->GetSupportedFormats()->at(0);
  EXPECT_EQ(cricket::CS_RUNNING, capturer_->Start(capture_format_));
  EXPECT_TRUE_WAIT(!capturer_->IsRunning(), 1000);
  EXPECT_EQ(1, listener.frame_count());
}

TEST_F(FileVideoCapturerTest, TestFileDevices) {
  cricket::Device not_a_file("I'm a camera", "with an id");
  EXPECT_FALSE(
      cricket::FileVideoCapturer::IsFileVideoCapturerDevice(not_a_file));
  const std::string test_file =
      cricket::GetTestFilePath("captured-320x240-2s-48.frames");
  cricket::Device file_device =
      cricket::FileVideoCapturer::CreateFileVideoCapturerDevice(test_file);
  EXPECT_TRUE(
      cricket::FileVideoCapturer::IsFileVideoCapturerDevice(file_device));
  EXPECT_TRUE(capturer_->Init(file_device));
  EXPECT_EQ(file_device.id, capturer_->GetId());
}

}  // unnamed namespace
