/*
 *  Copyright (c) 2013 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 <memory>

#include "webrtc/api/video/i420_buffer.h"
#include "webrtc/common_video/include/video_frame.h"
#include "webrtc/modules/video_coding/utility/quality_scaler.h"
#include "webrtc/rtc_base/event.h"
#include "webrtc/rtc_base/fakeclock.h"
#include "webrtc/test/gmock.h"
#include "webrtc/test/gtest.h"
#include "webrtc/video/overuse_frame_detector.h"

namespace webrtc {

using ::testing::InvokeWithoutArgs;

namespace {
  const int kWidth = 640;
  const int kHeight = 480;
  const int kFrameIntervalUs = 33 * rtc::kNumMicrosecsPerMillisec;
  const int kProcessTimeUs = 5 * rtc::kNumMicrosecsPerMillisec;
}  // namespace

class MockCpuOveruseObserver : public AdaptationObserverInterface {
 public:
  MockCpuOveruseObserver() {}
  virtual ~MockCpuOveruseObserver() {}

  MOCK_METHOD1(AdaptUp, void(AdaptReason));
  MOCK_METHOD1(AdaptDown, void(AdaptReason));
};

class CpuOveruseObserverImpl : public AdaptationObserverInterface {
 public:
  CpuOveruseObserverImpl() :
    overuse_(0),
    normaluse_(0) {}
  virtual ~CpuOveruseObserverImpl() {}

  void AdaptDown(AdaptReason) { ++overuse_; }
  void AdaptUp(AdaptReason) { ++normaluse_; }

  int overuse_;
  int normaluse_;
};

class OveruseFrameDetectorUnderTest : public OveruseFrameDetector {
 public:
  OveruseFrameDetectorUnderTest(const CpuOveruseOptions& options,
                                AdaptationObserverInterface* overuse_observer,
                                EncodedFrameObserver* encoder_timing,
                                CpuOveruseMetricsObserver* metrics_observer)
      : OveruseFrameDetector(options,
                             overuse_observer,
                             encoder_timing,
                             metrics_observer) {}
  ~OveruseFrameDetectorUnderTest() {}

  using OveruseFrameDetector::CheckForOveruse;
};

class OveruseFrameDetectorTest : public ::testing::Test,
                                 public CpuOveruseMetricsObserver {
 protected:
  void SetUp() override {
    observer_.reset(new MockCpuOveruseObserver());
    options_.min_process_count = 0;
    ReinitializeOveruseDetector();
  }

  void ReinitializeOveruseDetector() {
    overuse_detector_.reset(new OveruseFrameDetectorUnderTest(
        options_, observer_.get(), nullptr, this));
  }

  void OnEncodedFrameTimeMeasured(int encode_time_ms,
                                  const CpuOveruseMetrics& metrics) override {
    metrics_ = metrics;
  }

  int InitialUsage() {
    return ((options_.low_encode_usage_threshold_percent +
             options_.high_encode_usage_threshold_percent) / 2.0f) + 0.5;
  }

  void InsertAndSendFramesWithInterval(int num_frames,
                                       int interval_us,
                                       int width,
                                       int height,
                                       int delay_us) {
    VideoFrame frame(I420Buffer::Create(width, height),
                     webrtc::kVideoRotation_0, 0);
    uint32_t timestamp = 0;
    while (num_frames-- > 0) {
      frame.set_timestamp(timestamp);
      overuse_detector_->FrameCaptured(frame, rtc::TimeMicros());
      clock_.AdvanceTimeMicros(delay_us);
      overuse_detector_->FrameSent(timestamp, rtc::TimeMicros());
      clock_.AdvanceTimeMicros(interval_us - delay_us);
      timestamp += interval_us * 90 / 1000;
    }
  }

  void ForceUpdate(int width, int height) {
    // Insert one frame, wait a second and then put in another to force update
    // the usage. From the tests where these are used, adding another sample
    // doesn't affect the expected outcome (this is mainly to check initial
    // values and whether the overuse detector has been reset or not).
    InsertAndSendFramesWithInterval(2, rtc::kNumMicrosecsPerSec,
                                    width, height, kFrameIntervalUs);
  }
  void TriggerOveruse(int num_times) {
    const int kDelayUs = 32 * rtc::kNumMicrosecsPerMillisec;
    for (int i = 0; i < num_times; ++i) {
      InsertAndSendFramesWithInterval(
          1000, kFrameIntervalUs, kWidth, kHeight, kDelayUs);
      overuse_detector_->CheckForOveruse();
    }
  }

  void TriggerUnderuse() {
    const int kDelayUs1 = 5000;
    const int kDelayUs2 = 6000;
    InsertAndSendFramesWithInterval(
        1300, kFrameIntervalUs, kWidth, kHeight, kDelayUs1);
    InsertAndSendFramesWithInterval(
        1, kFrameIntervalUs, kWidth, kHeight, kDelayUs2);
    overuse_detector_->CheckForOveruse();
  }

  int UsagePercent() { return metrics_.encode_usage_percent; }

  int64_t OveruseProcessingTimeLimitForFramerate(int fps) const {
    int64_t frame_interval = rtc::kNumMicrosecsPerSec / fps;
    int64_t max_processing_time_us =
        (frame_interval * options_.high_encode_usage_threshold_percent) / 100;
    return max_processing_time_us;
  }

  int64_t UnderuseProcessingTimeLimitForFramerate(int fps) const {
    int64_t frame_interval = rtc::kNumMicrosecsPerSec / fps;
    int64_t max_processing_time_us =
        (frame_interval * options_.low_encode_usage_threshold_percent) / 100;
    return max_processing_time_us;
  }

  CpuOveruseOptions options_;
  rtc::ScopedFakeClock clock_;
  std::unique_ptr<MockCpuOveruseObserver> observer_;
  std::unique_ptr<OveruseFrameDetectorUnderTest> overuse_detector_;
  CpuOveruseMetrics metrics_;

  static const auto reason_ = AdaptationObserverInterface::AdaptReason::kCpu;
};


// UsagePercent() > high_encode_usage_threshold_percent => overuse.
// UsagePercent() < low_encode_usage_threshold_percent => underuse.
TEST_F(OveruseFrameDetectorTest, TriggerOveruse) {
  // usage > high => overuse
  EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(1);
  TriggerOveruse(options_.high_threshold_consecutive_count);
}

TEST_F(OveruseFrameDetectorTest, OveruseAndRecover) {
  // usage > high => overuse
  EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(1);
  TriggerOveruse(options_.high_threshold_consecutive_count);
  // usage < low => underuse
  EXPECT_CALL(*(observer_.get()), AdaptUp(reason_)).Times(testing::AtLeast(1));
  TriggerUnderuse();
}

TEST_F(OveruseFrameDetectorTest, OveruseAndRecoverWithNoObserver) {
  overuse_detector_.reset(new OveruseFrameDetectorUnderTest(
      options_, nullptr, nullptr, this));
  EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(0);
  TriggerOveruse(options_.high_threshold_consecutive_count);
  EXPECT_CALL(*(observer_.get()), AdaptUp(reason_)).Times(0);
  TriggerUnderuse();
}

TEST_F(OveruseFrameDetectorTest, DoubleOveruseAndRecover) {
  EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(2);
  TriggerOveruse(options_.high_threshold_consecutive_count);
  TriggerOveruse(options_.high_threshold_consecutive_count);
  EXPECT_CALL(*(observer_.get()), AdaptUp(reason_)).Times(testing::AtLeast(1));
  TriggerUnderuse();
}

TEST_F(OveruseFrameDetectorTest, TriggerUnderuseWithMinProcessCount) {
  const int kProcessIntervalUs = 5 * rtc::kNumMicrosecsPerSec;
  options_.min_process_count = 1;
  CpuOveruseObserverImpl overuse_observer;
  overuse_detector_.reset(new OveruseFrameDetectorUnderTest(
      options_, &overuse_observer, nullptr, this));
  InsertAndSendFramesWithInterval(
      1200, kFrameIntervalUs, kWidth, kHeight, kProcessTimeUs);
  overuse_detector_->CheckForOveruse();
  EXPECT_EQ(0, overuse_observer.normaluse_);
  clock_.AdvanceTimeMicros(kProcessIntervalUs);
  overuse_detector_->CheckForOveruse();
  EXPECT_EQ(1, overuse_observer.normaluse_);
}

TEST_F(OveruseFrameDetectorTest, ConstantOveruseGivesNoNormalUsage) {
  EXPECT_CALL(*(observer_.get()), AdaptUp(reason_)).Times(0);
  EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(64);
  for (size_t i = 0; i < 64; ++i) {
    TriggerOveruse(options_.high_threshold_consecutive_count);
  }
}

TEST_F(OveruseFrameDetectorTest, ConsecutiveCountTriggersOveruse) {
  EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(1);
  options_.high_threshold_consecutive_count = 2;
  ReinitializeOveruseDetector();
  TriggerOveruse(2);
}

TEST_F(OveruseFrameDetectorTest, IncorrectConsecutiveCountTriggersNoOveruse) {
  EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(0);
  options_.high_threshold_consecutive_count = 2;
  ReinitializeOveruseDetector();
  TriggerOveruse(1);
}

TEST_F(OveruseFrameDetectorTest, ProcessingUsage) {
  InsertAndSendFramesWithInterval(
      1000, kFrameIntervalUs, kWidth, kHeight, kProcessTimeUs);
  EXPECT_EQ(kProcessTimeUs * 100 / kFrameIntervalUs, UsagePercent());
}

TEST_F(OveruseFrameDetectorTest, ResetAfterResolutionChange) {
  ForceUpdate(kWidth, kHeight);
  EXPECT_EQ(InitialUsage(), UsagePercent());
  InsertAndSendFramesWithInterval(
      1000, kFrameIntervalUs, kWidth, kHeight, kProcessTimeUs);
  EXPECT_NE(InitialUsage(), UsagePercent());
  // Verify reset (with new width/height).
  ForceUpdate(kWidth, kHeight + 1);
  EXPECT_EQ(InitialUsage(), UsagePercent());
}

TEST_F(OveruseFrameDetectorTest, ResetAfterFrameTimeout) {
  ForceUpdate(kWidth, kHeight);
  EXPECT_EQ(InitialUsage(), UsagePercent());
  InsertAndSendFramesWithInterval(
      1000, kFrameIntervalUs, kWidth, kHeight, kProcessTimeUs);
  EXPECT_NE(InitialUsage(), UsagePercent());
  InsertAndSendFramesWithInterval(
      2, options_.frame_timeout_interval_ms *
      rtc::kNumMicrosecsPerMillisec, kWidth, kHeight, kProcessTimeUs);
  EXPECT_NE(InitialUsage(), UsagePercent());
  // Verify reset.
  InsertAndSendFramesWithInterval(
      2, (options_.frame_timeout_interval_ms + 1) *
      rtc::kNumMicrosecsPerMillisec, kWidth, kHeight, kProcessTimeUs);
  ForceUpdate(kWidth, kHeight);
  EXPECT_EQ(InitialUsage(), UsagePercent());
}

TEST_F(OveruseFrameDetectorTest, MinFrameSamplesBeforeUpdating) {
  options_.min_frame_samples = 40;
  ReinitializeOveruseDetector();
  InsertAndSendFramesWithInterval(
      40, kFrameIntervalUs, kWidth, kHeight, kProcessTimeUs);
  EXPECT_EQ(InitialUsage(), UsagePercent());
  // Pass time far enough to digest all previous samples.
  clock_.AdvanceTimeMicros(rtc::kNumMicrosecsPerSec);
  InsertAndSendFramesWithInterval(1, kFrameIntervalUs, kWidth, kHeight,
                                  kProcessTimeUs);
  // The last sample has not been processed here.
  EXPECT_EQ(InitialUsage(), UsagePercent());

  // Pass time far enough to digest all previous samples, 41 in total.
  clock_.AdvanceTimeMicros(rtc::kNumMicrosecsPerSec);
  InsertAndSendFramesWithInterval(
      1, kFrameIntervalUs, kWidth, kHeight, kProcessTimeUs);
  EXPECT_NE(InitialUsage(), UsagePercent());
}

TEST_F(OveruseFrameDetectorTest, InitialProcessingUsage) {
  ForceUpdate(kWidth, kHeight);
  EXPECT_EQ(InitialUsage(), UsagePercent());
}

TEST_F(OveruseFrameDetectorTest, MeasuresMultipleConcurrentSamples) {
  EXPECT_CALL(*(observer_.get()), AdaptDown(reason_))
      .Times(testing::AtLeast(1));
  static const int kIntervalUs = 33 * rtc::kNumMicrosecsPerMillisec;
  static const size_t kNumFramesEncodingDelay = 3;
  VideoFrame frame(I420Buffer::Create(kWidth, kHeight),
                   webrtc::kVideoRotation_0, 0);
  for (size_t i = 0; i < 1000; ++i) {
    // Unique timestamps.
    frame.set_timestamp(static_cast<uint32_t>(i));
    overuse_detector_->FrameCaptured(frame, rtc::TimeMicros());
    clock_.AdvanceTimeMicros(kIntervalUs);
    if (i > kNumFramesEncodingDelay) {
      overuse_detector_->FrameSent(
          static_cast<uint32_t>(i - kNumFramesEncodingDelay),
          rtc::TimeMicros());
    }
    overuse_detector_->CheckForOveruse();
  }
}

TEST_F(OveruseFrameDetectorTest, UpdatesExistingSamples) {
  // >85% encoding time should trigger overuse.
  EXPECT_CALL(*(observer_.get()), AdaptDown(reason_))
      .Times(testing::AtLeast(1));
  static const int kIntervalUs = 33 * rtc::kNumMicrosecsPerMillisec;
  static const int kDelayUs = 30 * rtc::kNumMicrosecsPerMillisec;
  VideoFrame frame(I420Buffer::Create(kWidth, kHeight),
                   webrtc::kVideoRotation_0, 0);
  uint32_t timestamp = 0;
  for (size_t i = 0; i < 1000; ++i) {
    frame.set_timestamp(timestamp);
    overuse_detector_->FrameCaptured(frame, rtc::TimeMicros());
    // Encode and send first parts almost instantly.
    clock_.AdvanceTimeMicros(rtc::kNumMicrosecsPerMillisec);
    overuse_detector_->FrameSent(timestamp, rtc::TimeMicros());
    // Encode heavier part, resulting in >85% usage total.
    clock_.AdvanceTimeMicros(kDelayUs - rtc::kNumMicrosecsPerMillisec);
    overuse_detector_->FrameSent(timestamp, rtc::TimeMicros());
    clock_.AdvanceTimeMicros(kIntervalUs - kDelayUs);
    timestamp += kIntervalUs * 90 / 1000;
    overuse_detector_->CheckForOveruse();
  }
}

TEST_F(OveruseFrameDetectorTest, RunOnTqNormalUsage) {
  rtc::TaskQueue queue("OveruseFrameDetectorTestQueue");

  rtc::Event event(false, false);
  queue.PostTask([this, &event] {
    overuse_detector_->StartCheckForOveruse();
    event.Set();
  });
  event.Wait(rtc::Event::kForever);

  // Expect NormalUsage(). When called, stop the |overuse_detector_| and then
  // set |event| to end the test.
  EXPECT_CALL(*(observer_.get()), AdaptUp(reason_))
      .WillOnce(InvokeWithoutArgs([this, &event] {
        overuse_detector_->StopCheckForOveruse();
        event.Set();
      }));

  queue.PostTask([this, &event] {
    const int kDelayUs1 = 5 * rtc::kNumMicrosecsPerMillisec;
    const int kDelayUs2 = 6 * rtc::kNumMicrosecsPerMillisec;
    InsertAndSendFramesWithInterval(1300, kFrameIntervalUs, kWidth, kHeight,
                                    kDelayUs1);
    InsertAndSendFramesWithInterval(1, kFrameIntervalUs, kWidth, kHeight,
                                    kDelayUs2);
  });

  EXPECT_TRUE(event.Wait(10000));
}

TEST_F(OveruseFrameDetectorTest, MaxIntervalScalesWithFramerate) {
  const int kCapturerMaxFrameRate = 30;
  const int kEncodeMaxFrameRate = 20;  // Maximum fps the encoder can sustain.

  // Trigger overuse.
  int64_t frame_interval_us = rtc::kNumMicrosecsPerSec / kCapturerMaxFrameRate;
  // Processing time just below over use limit given kEncodeMaxFrameRate.
  int64_t processing_time_us =
      (98 * OveruseProcessingTimeLimitForFramerate(kEncodeMaxFrameRate)) / 100;
  EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(1);
  for (int i = 0; i < options_.high_threshold_consecutive_count; ++i) {
    InsertAndSendFramesWithInterval(1200, frame_interval_us, kWidth, kHeight,
                                    processing_time_us);
    overuse_detector_->CheckForOveruse();
  }

  // Simulate frame rate reduction and normal usage.
  frame_interval_us = rtc::kNumMicrosecsPerSec / kEncodeMaxFrameRate;
  overuse_detector_->OnTargetFramerateUpdated(kEncodeMaxFrameRate);
  EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(0);
  for (int i = 0; i < options_.high_threshold_consecutive_count; ++i) {
    InsertAndSendFramesWithInterval(1200, frame_interval_us, kWidth, kHeight,
                                    processing_time_us);
    overuse_detector_->CheckForOveruse();
  }

  // Reduce processing time to trigger underuse.
  processing_time_us =
      (98 * UnderuseProcessingTimeLimitForFramerate(kEncodeMaxFrameRate)) / 100;
  EXPECT_CALL(*(observer_.get()), AdaptUp(reason_)).Times(1);
  InsertAndSendFramesWithInterval(1200, frame_interval_us, kWidth, kHeight,
                                  processing_time_us);
  overuse_detector_->CheckForOveruse();
}

TEST_F(OveruseFrameDetectorTest, RespectsMinFramerate) {
  const int kMinFrameRate = 7;  // Minimum fps allowed by current detector impl.
  overuse_detector_->OnTargetFramerateUpdated(kMinFrameRate);

  // Normal usage just at the limit.
  int64_t frame_interval_us = rtc::kNumMicrosecsPerSec / kMinFrameRate;
  // Processing time just below over use limit given kEncodeMaxFrameRate.
  int64_t processing_time_us =
      (98 * OveruseProcessingTimeLimitForFramerate(kMinFrameRate)) / 100;
  EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(0);
  for (int i = 0; i < options_.high_threshold_consecutive_count; ++i) {
    InsertAndSendFramesWithInterval(1200, frame_interval_us, kWidth, kHeight,
                                    processing_time_us);
    overuse_detector_->CheckForOveruse();
  }

  // Over the limit to overuse.
  processing_time_us =
      (102 * OveruseProcessingTimeLimitForFramerate(kMinFrameRate)) / 100;
  EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(1);
  for (int i = 0; i < options_.high_threshold_consecutive_count; ++i) {
    InsertAndSendFramesWithInterval(1200, frame_interval_us, kWidth, kHeight,
                                    processing_time_us);
    overuse_detector_->CheckForOveruse();
  }

  // Reduce input frame rate. Should still trigger overuse.
  overuse_detector_->OnTargetFramerateUpdated(kMinFrameRate - 1);
  EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(1);
  for (int i = 0; i < options_.high_threshold_consecutive_count; ++i) {
    InsertAndSendFramesWithInterval(1200, frame_interval_us, kWidth, kHeight,
                                    processing_time_us);
    overuse_detector_->CheckForOveruse();
  }
}

TEST_F(OveruseFrameDetectorTest, LimitsMaxFrameInterval) {
  const int kMaxFrameRate = 20;
  overuse_detector_->OnTargetFramerateUpdated(kMaxFrameRate);
  int64_t frame_interval_us = rtc::kNumMicrosecsPerSec / kMaxFrameRate;
  // Maximum frame interval allowed is 35% above ideal.
  int64_t max_frame_interval_us = (135 * frame_interval_us) / 100;
  // Maximum processing time, without triggering overuse, allowed with the above
  // frame interval.
  int64_t max_processing_time_us =
      (max_frame_interval_us * options_.high_encode_usage_threshold_percent) /
      100;

  // Processing time just below overuse limit given kMaxFrameRate.
  int64_t processing_time_us = (98 * max_processing_time_us) / 100;
  EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(0);
  for (int i = 0; i < options_.high_threshold_consecutive_count; ++i) {
    InsertAndSendFramesWithInterval(1200, max_frame_interval_us, kWidth,
                                    kHeight, processing_time_us);
    overuse_detector_->CheckForOveruse();
  }

  // Go above limit, trigger overuse.
  processing_time_us = (102 * max_processing_time_us) / 100;
  EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(1);
  for (int i = 0; i < options_.high_threshold_consecutive_count; ++i) {
    InsertAndSendFramesWithInterval(1200, max_frame_interval_us, kWidth,
                                    kHeight, processing_time_us);
    overuse_detector_->CheckForOveruse();
  }

  // Increase frame interval, should still trigger overuse.
  max_frame_interval_us *= 2;
  EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(1);
  for (int i = 0; i < options_.high_threshold_consecutive_count; ++i) {
    InsertAndSendFramesWithInterval(1200, max_frame_interval_us, kWidth,
                                    kHeight, processing_time_us);
    overuse_detector_->CheckForOveruse();
  }
}

}  // namespace webrtc
