/*
 *  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 "webrtc/video_engine/overuse_frame_detector.h"

#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

#include "webrtc/base/scoped_ptr.h"
#include "webrtc/system_wrappers/include/clock.h"

namespace webrtc {
namespace {
  const int kWidth = 640;
  const int kHeight = 480;
  const int kFrameInterval33ms = 33;
  const int kProcessIntervalMs = 5000;
  const int kProcessTime5ms = 5;
}  // namespace

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

  MOCK_METHOD0(OveruseDetected, void());
  MOCK_METHOD0(NormalUsage, void());
};

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

  void OveruseDetected() { ++overuse_; }
  void NormalUsage() { ++normaluse_; }

  int overuse_;
  int normaluse_;
};

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

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

  void CpuOveruseMetricsUpdated(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_ms, int width, int height, int delay_ms) {
    while (num_frames-- > 0) {
      int64_t capture_time_ms = clock_->TimeInMilliseconds();
      overuse_detector_->FrameCaptured(width, height, capture_time_ms);
      clock_->AdvanceTimeMilliseconds(delay_ms);
      overuse_detector_->FrameEncoded(delay_ms);
      overuse_detector_->FrameSent(capture_time_ms);
      clock_->AdvanceTimeMilliseconds(interval_ms - delay_ms);
    }
  }

  void TriggerOveruse(int num_times) {
    const int kDelayMs = 32;
    for (int i = 0; i < num_times; ++i) {
      InsertAndSendFramesWithInterval(
          1000, kFrameInterval33ms, kWidth, kHeight, kDelayMs);
      overuse_detector_->Process();
    }
  }

  void TriggerUnderuse() {
    const int kDelayMs1 = 5;
    const int kDelayMs2 = 6;
    InsertAndSendFramesWithInterval(
        1300, kFrameInterval33ms, kWidth, kHeight, kDelayMs1);
    InsertAndSendFramesWithInterval(
        1, kFrameInterval33ms, kWidth, kHeight, kDelayMs2);
    overuse_detector_->Process();
  }

  int AvgEncodeTimeMs() { return metrics_.avg_encode_time_ms; }

  int UsagePercent() { return metrics_.encode_usage_percent; }

  CpuOveruseOptions options_;
  rtc::scoped_ptr<SimulatedClock> clock_;
  rtc::scoped_ptr<MockCpuOveruseObserver> observer_;
  rtc::scoped_ptr<OveruseFrameDetector> overuse_detector_;
  CpuOveruseMetrics metrics_;
};


// enable_encode_usage_method = true;
// enable_extended_processing_usage = false;
// UsagePercent() > high_encode_usage_threshold_percent => overuse.
// UsagePercent() < low_encode_usage_threshold_percent => underuse.
TEST_F(OveruseFrameDetectorTest, TriggerOveruse) {
  options_.enable_extended_processing_usage = false;
  ReinitializeOveruseDetector();
  // usage > high => overuse
  EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(1);
  TriggerOveruse(options_.high_threshold_consecutive_count);
}

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

TEST_F(OveruseFrameDetectorTest, OveruseAndRecoverWithNoObserver) {
  options_.enable_extended_processing_usage = false;
  overuse_detector_.reset(
      new OveruseFrameDetector(clock_.get(), options_, nullptr, this));
  EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(0);
  TriggerOveruse(options_.high_threshold_consecutive_count);
  EXPECT_CALL(*(observer_.get()), NormalUsage()).Times(0);
  TriggerUnderuse();
}

TEST_F(OveruseFrameDetectorTest, OveruseAndRecoverWithMethodDisabled) {
  options_.enable_encode_usage_method = false;
  options_.enable_extended_processing_usage = false;
  ReinitializeOveruseDetector();
  EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(0);
  TriggerOveruse(options_.high_threshold_consecutive_count);
  EXPECT_CALL(*(observer_.get()), NormalUsage()).Times(0);
  TriggerUnderuse();
}

TEST_F(OveruseFrameDetectorTest, DoubleOveruseAndRecover) {
  options_.enable_extended_processing_usage = false;
  ReinitializeOveruseDetector();
  EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(2);
  TriggerOveruse(options_.high_threshold_consecutive_count);
  TriggerOveruse(options_.high_threshold_consecutive_count);
  EXPECT_CALL(*(observer_.get()), NormalUsage()).Times(testing::AtLeast(1));
  TriggerUnderuse();
}

TEST_F(OveruseFrameDetectorTest, TriggerUnderuseWithMinProcessCount) {
  options_.enable_extended_processing_usage = false;
  options_.min_process_count = 1;
  CpuOveruseObserverImpl overuse_observer;
  overuse_detector_.reset(new OveruseFrameDetector(clock_.get(), options_,
                                                   &overuse_observer, this));
  InsertAndSendFramesWithInterval(
      1200, kFrameInterval33ms, kWidth, kHeight, kProcessTime5ms);
  overuse_detector_->Process();
  EXPECT_EQ(0, overuse_observer.normaluse_);
  clock_->AdvanceTimeMilliseconds(kProcessIntervalMs);
  overuse_detector_->Process();
  EXPECT_EQ(1, overuse_observer.normaluse_);
}

TEST_F(OveruseFrameDetectorTest, ConstantOveruseGivesNoNormalUsage) {
  options_.enable_extended_processing_usage = false;
  ReinitializeOveruseDetector();
  EXPECT_CALL(*(observer_.get()), NormalUsage()).Times(0);
  EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(64);
  for(size_t i = 0; i < 64; ++i) {
    TriggerOveruse(options_.high_threshold_consecutive_count);
  }
}

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

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

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

TEST_F(OveruseFrameDetectorTest, ResetAfterResolutionChange) {
  EXPECT_EQ(InitialUsage(), UsagePercent());
  InsertAndSendFramesWithInterval(
      1000, kFrameInterval33ms, kWidth, kHeight, kProcessTime5ms);
  EXPECT_NE(InitialUsage(), UsagePercent());
  // Verify reset.
  InsertAndSendFramesWithInterval(
      1, kFrameInterval33ms, kWidth, kHeight + 1, kProcessTime5ms);
  EXPECT_EQ(InitialUsage(), UsagePercent());
}

TEST_F(OveruseFrameDetectorTest, ResetAfterFrameTimeout) {
  EXPECT_EQ(InitialUsage(), UsagePercent());
  InsertAndSendFramesWithInterval(
      1000, kFrameInterval33ms, kWidth, kHeight, kProcessTime5ms);
  EXPECT_NE(InitialUsage(), UsagePercent());
  InsertAndSendFramesWithInterval(
      2, options_.frame_timeout_interval_ms, kWidth, kHeight, kProcessTime5ms);
  EXPECT_NE(InitialUsage(), UsagePercent());
  // Verify reset.
  InsertAndSendFramesWithInterval(
      2, options_.frame_timeout_interval_ms + 1, kWidth, kHeight,
      kProcessTime5ms);
  EXPECT_EQ(InitialUsage(), UsagePercent());
}

TEST_F(OveruseFrameDetectorTest, MinFrameSamplesBeforeUpdating) {
  options_.min_frame_samples = 40;
  ReinitializeOveruseDetector();
  InsertAndSendFramesWithInterval(
      40, kFrameInterval33ms, kWidth, kHeight, kProcessTime5ms);
  EXPECT_EQ(InitialUsage(), UsagePercent());
  InsertAndSendFramesWithInterval(
      1, kFrameInterval33ms, kWidth, kHeight, kProcessTime5ms);
  EXPECT_NE(InitialUsage(), UsagePercent());
}

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

TEST_F(OveruseFrameDetectorTest, FrameDelay_OneFrameDisabled) {
  options_.enable_extended_processing_usage = false;
  ReinitializeOveruseDetector();
  const int kProcessingTimeMs = 100;
  overuse_detector_->FrameCaptured(kWidth, kHeight, 33);
  clock_->AdvanceTimeMilliseconds(kProcessingTimeMs);
  overuse_detector_->FrameSent(33);
  EXPECT_EQ(-1, overuse_detector_->LastProcessingTimeMs());
}

TEST_F(OveruseFrameDetectorTest, FrameDelay_OneFrame) {
  options_.enable_extended_processing_usage = true;
  ReinitializeOveruseDetector();
  const int kProcessingTimeMs = 100;
  overuse_detector_->FrameCaptured(kWidth, kHeight, 33);
  clock_->AdvanceTimeMilliseconds(kProcessingTimeMs);
  EXPECT_EQ(-1, overuse_detector_->LastProcessingTimeMs());
  overuse_detector_->FrameSent(33);
  EXPECT_EQ(kProcessingTimeMs, overuse_detector_->LastProcessingTimeMs());
  EXPECT_EQ(0, overuse_detector_->FramesInQueue());
}

TEST_F(OveruseFrameDetectorTest, FrameDelay_TwoFrames) {
  options_.enable_extended_processing_usage = true;
  ReinitializeOveruseDetector();
  const int kProcessingTimeMs1 = 100;
  const int kProcessingTimeMs2 = 50;
  const int kTimeBetweenFramesMs = 200;
  overuse_detector_->FrameCaptured(kWidth, kHeight, 33);
  clock_->AdvanceTimeMilliseconds(kProcessingTimeMs1);
  overuse_detector_->FrameSent(33);
  EXPECT_EQ(kProcessingTimeMs1, overuse_detector_->LastProcessingTimeMs());
  clock_->AdvanceTimeMilliseconds(kTimeBetweenFramesMs);
  overuse_detector_->FrameCaptured(kWidth, kHeight, 66);
  clock_->AdvanceTimeMilliseconds(kProcessingTimeMs2);
  overuse_detector_->FrameSent(66);
  EXPECT_EQ(kProcessingTimeMs2, overuse_detector_->LastProcessingTimeMs());
}

TEST_F(OveruseFrameDetectorTest, FrameDelay_MaxQueueSize) {
  options_.enable_extended_processing_usage = true;
  ReinitializeOveruseDetector();
  const int kMaxQueueSize = 91;
  for (int i = 0; i < kMaxQueueSize * 2; ++i) {
    overuse_detector_->FrameCaptured(kWidth, kHeight, i);
  }
  EXPECT_EQ(kMaxQueueSize, overuse_detector_->FramesInQueue());
}

TEST_F(OveruseFrameDetectorTest, FrameDelay_NonProcessedFramesRemoved) {
  options_.enable_extended_processing_usage = true;
  ReinitializeOveruseDetector();
  const int kProcessingTimeMs = 100;
  overuse_detector_->FrameCaptured(kWidth, kHeight, 33);
  clock_->AdvanceTimeMilliseconds(kProcessingTimeMs);
  overuse_detector_->FrameCaptured(kWidth, kHeight, 35);
  clock_->AdvanceTimeMilliseconds(kProcessingTimeMs);
  overuse_detector_->FrameCaptured(kWidth, kHeight, 66);
  clock_->AdvanceTimeMilliseconds(kProcessingTimeMs);
  overuse_detector_->FrameCaptured(kWidth, kHeight, 99);
  clock_->AdvanceTimeMilliseconds(kProcessingTimeMs);
  EXPECT_EQ(-1, overuse_detector_->LastProcessingTimeMs());
  EXPECT_EQ(4, overuse_detector_->FramesInQueue());
  overuse_detector_->FrameSent(66);
  // Frame 33, 35 removed, 66 processed, 99 not processed.
  EXPECT_EQ(2 * kProcessingTimeMs, overuse_detector_->LastProcessingTimeMs());
  EXPECT_EQ(1, overuse_detector_->FramesInQueue());
  overuse_detector_->FrameSent(99);
  EXPECT_EQ(kProcessingTimeMs, overuse_detector_->LastProcessingTimeMs());
  EXPECT_EQ(0, overuse_detector_->FramesInQueue());
}

TEST_F(OveruseFrameDetectorTest, FrameDelay_ResetClearsFrames) {
  options_.enable_extended_processing_usage = true;
  ReinitializeOveruseDetector();
  const int kProcessingTimeMs = 100;
  overuse_detector_->FrameCaptured(kWidth, kHeight, 33);
  EXPECT_EQ(1, overuse_detector_->FramesInQueue());
  clock_->AdvanceTimeMilliseconds(kProcessingTimeMs);
  // Verify reset (resolution changed).
  overuse_detector_->FrameCaptured(kWidth, kHeight + 1, 66);
  EXPECT_EQ(1, overuse_detector_->FramesInQueue());
  clock_->AdvanceTimeMilliseconds(kProcessingTimeMs);
  overuse_detector_->FrameSent(66);
  EXPECT_EQ(kProcessingTimeMs, overuse_detector_->LastProcessingTimeMs());
  EXPECT_EQ(0, overuse_detector_->FramesInQueue());
}

TEST_F(OveruseFrameDetectorTest, FrameDelay_NonMatchingSendFrameIgnored) {
  options_.enable_extended_processing_usage = true;
  ReinitializeOveruseDetector();
  const int kProcessingTimeMs = 100;
  overuse_detector_->FrameCaptured(kWidth, kHeight, 33);
  clock_->AdvanceTimeMilliseconds(kProcessingTimeMs);
  overuse_detector_->FrameSent(34);
  EXPECT_EQ(-1, overuse_detector_->LastProcessingTimeMs());
  overuse_detector_->FrameSent(33);
  EXPECT_EQ(kProcessingTimeMs, overuse_detector_->LastProcessingTimeMs());
}

TEST_F(OveruseFrameDetectorTest, EncodedFrame) {
  const int kInitialAvgEncodeTimeInMs = 5;
  EXPECT_EQ(kInitialAvgEncodeTimeInMs, AvgEncodeTimeMs());
  for (int i = 0; i < 30; i++) {
    clock_->AdvanceTimeMilliseconds(33);
    overuse_detector_->FrameEncoded(2);
  }
  EXPECT_EQ(2, AvgEncodeTimeMs());
}

// enable_encode_usage_method = true;
// enable_extended_processing_usage = true;
// UsagePercent() > high_encode_usage_threshold_percent => overuse.
// UsagePercent() < low_encode_usage_threshold_percent => underuse.
TEST_F(OveruseFrameDetectorTest, TriggerOveruseWithExtendedProcessingUsage) {
  options_.enable_extended_processing_usage = true;
  ReinitializeOveruseDetector();
  // usage > high => overuse
  EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(1);
  TriggerOveruse(options_.high_threshold_consecutive_count);
}

TEST_F(OveruseFrameDetectorTest, OveruseAndRecoverWithExtendedProcessingUsage) {
  options_.enable_extended_processing_usage = true;
  ReinitializeOveruseDetector();
  // usage > high => overuse
  EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(1);
  TriggerOveruse(options_.high_threshold_consecutive_count);
  // usage < low => underuse
  EXPECT_CALL(*(observer_.get()), NormalUsage()).Times(testing::AtLeast(1));
  TriggerUnderuse();
}

TEST_F(OveruseFrameDetectorTest,
       OveruseAndRecoverWithExtendedProcessingUsageMethodDisabled) {
  options_.enable_encode_usage_method = false;
  options_.enable_extended_processing_usage = true;
  ReinitializeOveruseDetector();
  // usage > high => overuse
  EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(0);
  TriggerOveruse(options_.high_threshold_consecutive_count);
  // usage < low => underuse
  EXPECT_CALL(*(observer_.get()), NormalUsage()).Times(0);
  TriggerUnderuse();
}

}  // namespace webrtc
