/*
 *  Copyright 2020 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 "video/adaptation/quality_scaler_resource.h"

#include <memory>

#include "absl/types/optional.h"
#include "api/task_queue/default_task_queue_factory.h"
#include "api/task_queue/task_queue_factory.h"
#include "api/video_codecs/video_encoder.h"
#include "rtc_base/event.h"
#include "rtc_base/task_queue.h"
#include "test/gtest.h"

namespace webrtc {

namespace {

const int kDefaultTimeout = 5000;

class FakeQualityScalerQpUsageHandlerCallback
    : public QualityScalerQpUsageHandlerCallbackInterface {
 public:
  explicit FakeQualityScalerQpUsageHandlerCallback(
      rtc::TaskQueue* encoder_queue)
      : QualityScalerQpUsageHandlerCallbackInterface(),
        encoder_queue_(encoder_queue),
        is_handled_(false),
        qp_usage_handled_event_(true /* manual_reset */, false),
        clear_qp_samples_result_(absl::nullopt) {}
  ~FakeQualityScalerQpUsageHandlerCallback() override {
    RTC_DCHECK(is_handled_)
        << "The callback was destroyed without being invoked.";
  }

  void OnQpUsageHandled(bool clear_qp_samples) override {
    ASSERT_TRUE(encoder_queue_->IsCurrent());
    RTC_DCHECK(!is_handled_);
    clear_qp_samples_result_ = clear_qp_samples;
    is_handled_ = true;
    qp_usage_handled_event_.Set();
  }

  bool is_handled() const { return is_handled_; }
  rtc::Event* qp_usage_handled_event() { return &qp_usage_handled_event_; }
  absl::optional<bool> clear_qp_samples_result() const {
    return clear_qp_samples_result_;
  }

 private:
  rtc::TaskQueue* const encoder_queue_;
  bool is_handled_;
  rtc::Event qp_usage_handled_event_;
  absl::optional<bool> clear_qp_samples_result_;
};

}  // namespace

class QualityScalerResourceTest : public ::testing::Test {
 public:
  QualityScalerResourceTest()
      : task_queue_factory_(CreateDefaultTaskQueueFactory()),
        resource_adaptation_queue_(task_queue_factory_->CreateTaskQueue(
            "ResourceAdaptationQueue",
            TaskQueueFactory::Priority::NORMAL)),
        encoder_queue_(task_queue_factory_->CreateTaskQueue(
            "EncoderQueue",
            TaskQueueFactory::Priority::NORMAL)),
        quality_scaler_resource_(new QualityScalerResource()) {
    quality_scaler_resource_->Initialize(&encoder_queue_,
                                         &resource_adaptation_queue_);
    rtc::Event event;
    encoder_queue_.PostTask([this, &event] {
      quality_scaler_resource_->StartCheckForOveruse(
          VideoEncoder::QpThresholds());
      event.Set();
    });
    event.Wait(kDefaultTimeout);
  }

  ~QualityScalerResourceTest() {
    rtc::Event event;
    encoder_queue_.PostTask([this, &event] {
      quality_scaler_resource_->StopCheckForOveruse();
      event.Set();
    });
    event.Wait(kDefaultTimeout);
  }

 protected:
  const std::unique_ptr<TaskQueueFactory> task_queue_factory_;
  rtc::TaskQueue resource_adaptation_queue_;
  rtc::TaskQueue encoder_queue_;
  rtc::scoped_refptr<QualityScalerResource> quality_scaler_resource_;
};

TEST_F(QualityScalerResourceTest, ReportQpHigh) {
  rtc::scoped_refptr<FakeQualityScalerQpUsageHandlerCallback> callback =
      new FakeQualityScalerQpUsageHandlerCallback(&encoder_queue_);
  encoder_queue_.PostTask([this, callback] {
    quality_scaler_resource_->OnReportQpUsageHigh(callback);
  });
  callback->qp_usage_handled_event()->Wait(kDefaultTimeout);
}

TEST_F(QualityScalerResourceTest, ReportQpLow) {
  rtc::scoped_refptr<FakeQualityScalerQpUsageHandlerCallback> callback =
      new FakeQualityScalerQpUsageHandlerCallback(&encoder_queue_);
  encoder_queue_.PostTask([this, callback] {
    quality_scaler_resource_->OnReportQpUsageLow(callback);
  });
  callback->qp_usage_handled_event()->Wait(kDefaultTimeout);
}

TEST_F(QualityScalerResourceTest, MultipleCallbacksInFlight) {
  rtc::scoped_refptr<FakeQualityScalerQpUsageHandlerCallback> callback1 =
      new FakeQualityScalerQpUsageHandlerCallback(&encoder_queue_);
  rtc::scoped_refptr<FakeQualityScalerQpUsageHandlerCallback> callback2 =
      new FakeQualityScalerQpUsageHandlerCallback(&encoder_queue_);
  rtc::scoped_refptr<FakeQualityScalerQpUsageHandlerCallback> callback3 =
      new FakeQualityScalerQpUsageHandlerCallback(&encoder_queue_);
  encoder_queue_.PostTask([this, callback1, callback2, callback3] {
    quality_scaler_resource_->OnReportQpUsageHigh(callback1);
    quality_scaler_resource_->OnReportQpUsageLow(callback2);
    quality_scaler_resource_->OnReportQpUsageHigh(callback3);
  });
  callback1->qp_usage_handled_event()->Wait(kDefaultTimeout);
  callback2->qp_usage_handled_event()->Wait(kDefaultTimeout);
  callback3->qp_usage_handled_event()->Wait(kDefaultTimeout);
}

TEST_F(QualityScalerResourceTest, AbortPendingCallbacksAndStartAgain) {
  rtc::scoped_refptr<FakeQualityScalerQpUsageHandlerCallback> callback1 =
      new FakeQualityScalerQpUsageHandlerCallback(&encoder_queue_);
  rtc::scoped_refptr<FakeQualityScalerQpUsageHandlerCallback> callback2 =
      new FakeQualityScalerQpUsageHandlerCallback(&encoder_queue_);
  encoder_queue_.PostTask([this, callback1, callback2] {
    quality_scaler_resource_->OnReportQpUsageHigh(callback1);
    quality_scaler_resource_->StopCheckForOveruse();
    EXPECT_TRUE(callback1->qp_usage_handled_event()->Wait(0));
    quality_scaler_resource_->StartCheckForOveruse(
        VideoEncoder::QpThresholds());
    quality_scaler_resource_->OnReportQpUsageHigh(callback2);
  });
  callback1->qp_usage_handled_event()->Wait(kDefaultTimeout);
  callback2->qp_usage_handled_event()->Wait(kDefaultTimeout);
}

}  // namespace webrtc
