/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include <stdio.h>
#include <string.h>
#include <fstream>
#include <memory>
#include <string>

#include "common_video/libyuv/include/webrtc_libyuv.h"
#include "rtc_tools/frame_editing/frame_editing_lib.h"
#include "test/gtest.h"
#include "test/testsupport/file_utils.h"

namespace webrtc {
namespace test {

const int kWidth = 352;
const int kHeight = 288;
const size_t kFrameSize = CalcBufferSize(VideoType::kI420, kWidth, kHeight);

class FrameEditingTest : public ::testing::Test {
 protected:
  virtual void SetUp() {
    reference_video_ = ResourcePath("foreman_cif", "yuv");
    test_video_ = webrtc::test::TempFilename(webrtc::test::OutputPath(),
                                             "frame_editing_unittest.yuv");

    original_fid_ = fopen(reference_video_.c_str(), "rb");
    ASSERT_TRUE(original_fid_ != NULL);

    // Ensure the output file exists on disk.
    std::ofstream(test_video_.c_str(), std::ios::out);
    // Open the output file for reading.
    // TODO(holmer): Figure out why this file has to be opened here (test fails
    // if it's opened after the write operation performed in EditFrames).
    edited_fid_ = fopen(test_video_.c_str(), "rb");
    ASSERT_TRUE(edited_fid_ != NULL);

    original_buffer_.reset(new int[kFrameSize]);
    edited_buffer_.reset(new int[kFrameSize]);
    num_frames_read_ = 0;
  }
  virtual void TearDown() {
    fclose(original_fid_);
    fclose(edited_fid_);
    remove(test_video_.c_str());
  }
  // Compares the frames in both streams to the end of one of the streams.
  void CompareToTheEnd(FILE* test_video_fid,
                       FILE* ref_video_fid,
                       std::unique_ptr<int[]>* ref_buffer,
                       std::unique_ptr<int[]>* test_buffer) {
    while (!feof(test_video_fid) && !feof(ref_video_fid)) {
      num_bytes_read_ = fread(ref_buffer->get(), 1, kFrameSize, ref_video_fid);
      if (!feof(ref_video_fid)) {
        EXPECT_EQ(kFrameSize, num_bytes_read_);
      }
      num_bytes_read_ =
          fread(test_buffer->get(), 1, kFrameSize, test_video_fid);
      if (!feof(test_video_fid)) {
        EXPECT_EQ(kFrameSize, num_bytes_read_);
      }
      if (!feof(test_video_fid) && !feof(test_video_fid)) {
        EXPECT_EQ(0, memcmp(ref_buffer->get(), test_buffer->get(), kFrameSize));
      }
    }
    // There should not be anything left in either stream.
    EXPECT_EQ(!feof(test_video_fid), !feof(ref_video_fid));
  }
  std::string reference_video_;
  std::string test_video_;
  FILE* original_fid_;
  FILE* edited_fid_;
  size_t num_bytes_read_;
  std::unique_ptr<int[]> original_buffer_;
  std::unique_ptr<int[]> edited_buffer_;
  int num_frames_read_;
};

TEST_F(FrameEditingTest, ValidInPath) {
  const int kFirstFrameToProcess = 160;
  const int kInterval = -1;
  const int kLastFrameToProcess = 240;

  int result =
      EditFrames(reference_video_, kWidth, kHeight, kFirstFrameToProcess,
                 kInterval, kLastFrameToProcess, test_video_);
  EXPECT_EQ(0, result);

  for (int i = 1; i < kFirstFrameToProcess; ++i) {
    num_bytes_read_ =
        fread(original_buffer_.get(), 1, kFrameSize, original_fid_);
    EXPECT_EQ(kFrameSize, num_bytes_read_);

    num_bytes_read_ = fread(edited_buffer_.get(), 1, kFrameSize, edited_fid_);
    EXPECT_EQ(kFrameSize, num_bytes_read_);

    EXPECT_EQ(0,
              memcmp(original_buffer_.get(), edited_buffer_.get(), kFrameSize));
  }
  // Do not compare the frames that have been cut.
  for (int i = kFirstFrameToProcess; i <= kLastFrameToProcess; ++i) {
    num_bytes_read_ =
        fread(original_buffer_.get(), 1, kFrameSize, original_fid_);
    EXPECT_EQ(kFrameSize, num_bytes_read_);
  }
  CompareToTheEnd(edited_fid_, original_fid_, &original_buffer_,
                  &edited_buffer_);
}

TEST_F(FrameEditingTest, EmptySetToCut) {
  const int kFirstFrameToProcess = 2;
  const int kInterval = -1;
  const int kLastFrameToProcess = 1;

  int result =
      EditFrames(reference_video_, kWidth, kHeight, kFirstFrameToProcess,
                 kInterval, kLastFrameToProcess, test_video_);
  EXPECT_EQ(-10, result);
}

TEST_F(FrameEditingTest, InValidInPath) {
  const std::string kRefVideo_ = "PATH/THAT/DOES/NOT/EXIST";

  const int kFirstFrameToProcess = 30;
  const int kInterval = 1;
  const int kLastFrameToProcess = 120;

  int result = EditFrames(kRefVideo_, kWidth, kHeight, kFirstFrameToProcess,
                          kInterval, kLastFrameToProcess, test_video_);
  EXPECT_EQ(-11, result);
}

TEST_F(FrameEditingTest, DeletingEverySecondFrame) {
  const int kFirstFrameToProcess = 1;
  const int kInterval = -2;
  const int kLastFrameToProcess = 10000;
  // Set kLastFrameToProcess to a large value so that all frame are processed.
  int result =
      EditFrames(reference_video_, kWidth, kHeight, kFirstFrameToProcess,
                 kInterval, kLastFrameToProcess, test_video_);
  EXPECT_EQ(0, result);

  while (!feof(original_fid_) && !feof(edited_fid_)) {
    num_bytes_read_ =
        fread(original_buffer_.get(), 1, kFrameSize, original_fid_);
    if (!feof(original_fid_)) {
      EXPECT_EQ(kFrameSize, num_bytes_read_);
      num_frames_read_++;
    }
    // We want to compare every second frame of the original to the edited.
    // kInterval=-2 and (num_frames_read_ - 1) % kInterval  will be -1 for
    // every second frame.
    // num_frames_read_ - 1 because we have deleted frame number 2, 4 , 6 etc.
    if ((num_frames_read_ - 1) % kInterval == -1) {
      num_bytes_read_ = fread(edited_buffer_.get(), 1, kFrameSize, edited_fid_);
      if (!feof(edited_fid_)) {
        EXPECT_EQ(kFrameSize, num_bytes_read_);
      }
      if (!feof(original_fid_) && !feof(edited_fid_)) {
        EXPECT_EQ(0, memcmp(original_buffer_.get(), edited_buffer_.get(),
                            kFrameSize));
      }
    }
  }
}

TEST_F(FrameEditingTest, RepeatFrames) {
  const int kFirstFrameToProcess = 160;
  const int kInterval = 2;
  const int kLastFrameToProcess = 240;

  int result =
      EditFrames(reference_video_, kWidth, kHeight, kFirstFrameToProcess,
                 kInterval, kLastFrameToProcess, test_video_);
  EXPECT_EQ(0, result);

  for (int i = 1; i < kFirstFrameToProcess; ++i) {
    num_bytes_read_ =
        fread(original_buffer_.get(), 1, kFrameSize, original_fid_);
    EXPECT_EQ(kFrameSize, num_bytes_read_);

    num_bytes_read_ = fread(edited_buffer_.get(), 1, kFrameSize, edited_fid_);
    EXPECT_EQ(kFrameSize, num_bytes_read_);

    EXPECT_EQ(0,
              memcmp(original_buffer_.get(), edited_buffer_.get(), kFrameSize));
  }
  // Do not compare the frames that have been repeated.
  for (int i = kFirstFrameToProcess; i <= kLastFrameToProcess; ++i) {
    num_bytes_read_ =
        fread(original_buffer_.get(), 1, kFrameSize, original_fid_);
    EXPECT_EQ(kFrameSize, num_bytes_read_);
    for (int i = 1; i <= kInterval; ++i) {
      num_bytes_read_ = fread(edited_buffer_.get(), 1, kFrameSize, edited_fid_);
      EXPECT_EQ(kFrameSize, num_bytes_read_);
      EXPECT_EQ(
          0, memcmp(original_buffer_.get(), edited_buffer_.get(), kFrameSize));
    }
  }
  CompareToTheEnd(edited_fid_, original_fid_, &original_buffer_,
                  &edited_buffer_);
}
}  // namespace test
}  // namespace webrtc
