// Copyright 2021 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <memory>
#include <vector>

#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/run_loop.h"
#include "base/sequenced_task_runner.h"
#include "base/task/thread_pool.h"
#include "base/test/bind.h"
#include "base/test/gmock_callback_support.h"
#include "base/test/task_environment.h"
#include "media/base/media_util.h"
#include "media/base/mock_filters.h"
#include "media/base/offloading_audio_encoder.h"
#include "testing/gtest/include/gtest/gtest.h"

using ::base::test::RunCallback;
using ::base::test::RunOnceCallback;
using ::testing::_;
using ::testing::DoAll;
using ::testing::Invoke;
using ::testing::Return;

namespace media {

class OffloadingAudioEncoderTest : public testing::Test {
 protected:
  void SetUp() override {
    auto mock_audio_encoder = std::make_unique<MockAudioEncoder>();
    mock_audio_encoder_ = mock_audio_encoder.get();
    work_runner_ = base::ThreadPool::CreateSequencedTaskRunner({});
    callback_runner_ = base::SequencedTaskRunnerHandle::Get();
    offloading_encoder_ = std::make_unique<OffloadingAudioEncoder>(
        std::move(mock_audio_encoder), work_runner_, callback_runner_);
    EXPECT_CALL(*mock_audio_encoder_, OnDestruct()).WillOnce(Invoke([this]() {
      EXPECT_TRUE(work_runner_->RunsTasksInCurrentSequence());
    }));
  }

  void RunLoop() { task_environment_.RunUntilIdle(); }

  base::test::TaskEnvironment task_environment_;
  scoped_refptr<base::SequencedTaskRunner> work_runner_;
  scoped_refptr<base::SequencedTaskRunner> callback_runner_;
  MockAudioEncoder* mock_audio_encoder_;
  std::unique_ptr<OffloadingAudioEncoder> offloading_encoder_;
};

TEST_F(OffloadingAudioEncoderTest, Initialize) {
  bool called_done = false;
  bool called_output = false;
  AudioEncoder::Options options;
  AudioEncoder::OutputCB output_cb = base::BindLambdaForTesting(
      [&](EncodedAudioBuffer, absl::optional<AudioEncoder::CodecDescription>) {
        EXPECT_TRUE(callback_runner_->RunsTasksInCurrentSequence());
        called_output = true;
      });
  AudioEncoder::StatusCB done_cb = base::BindLambdaForTesting([&](Status s) {
    EXPECT_TRUE(callback_runner_->RunsTasksInCurrentSequence());
    called_done = true;
  });

  EXPECT_CALL(*mock_audio_encoder_, Initialize(_, _, _))
      .WillOnce(Invoke([this](const AudioEncoder::Options& options,
                              AudioEncoder::OutputCB output_cb,
                              AudioEncoder::StatusCB done_cb) {
        EXPECT_TRUE(work_runner_->RunsTasksInCurrentSequence());
        AudioParameters params;
        EncodedAudioBuffer buf(params, nullptr, 0, base::TimeTicks());
        std::move(done_cb).Run(Status());

        // Usually |output_cb| is not called by Initialize() but for this
        // test it doesn't matter. We only care about a task runner used
        // for running |output_cb|, and not what triggers those callback.
        std::move(output_cb).Run(std::move(buf), {});
      }));

  offloading_encoder_->Initialize(options, std::move(output_cb),
                                  std::move(done_cb));
  RunLoop();
  EXPECT_TRUE(called_done);
  EXPECT_TRUE(called_output);
}

TEST_F(OffloadingAudioEncoderTest, Encode) {
  bool called_done = false;
  AudioEncoder::StatusCB done_cb = base::BindLambdaForTesting([&](Status s) {
    EXPECT_TRUE(callback_runner_->RunsTasksInCurrentSequence());
    called_done = true;
  });

  EXPECT_CALL(*mock_audio_encoder_, Encode(_, _, _))
      .WillOnce(Invoke([this](std::unique_ptr<AudioBus> audio_bus,
                              base::TimeTicks capture_time,
                              AudioEncoder::StatusCB done_cb) {
        EXPECT_TRUE(work_runner_->RunsTasksInCurrentSequence());
        std::move(done_cb).Run(Status());
      }));

  base::TimeTicks ts;
  offloading_encoder_->Encode(nullptr, ts, std::move(done_cb));
  RunLoop();
  EXPECT_TRUE(called_done);
}

TEST_F(OffloadingAudioEncoderTest, Flush) {
  bool called_done = false;
  AudioEncoder::StatusCB done_cb = base::BindLambdaForTesting([&](Status s) {
    EXPECT_TRUE(callback_runner_->RunsTasksInCurrentSequence());
    called_done = true;
  });

  EXPECT_CALL(*mock_audio_encoder_, Flush(_))
      .WillOnce(Invoke([this](AudioEncoder::StatusCB done_cb) {
        EXPECT_TRUE(work_runner_->RunsTasksInCurrentSequence());
        std::move(done_cb).Run(Status());
      }));

  offloading_encoder_->Flush(std::move(done_cb));
  RunLoop();
  EXPECT_TRUE(called_done);
}

}  // namespace media
