// Copyright 2020 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 "media/remoting/receiver.h"

#include <utility>

#include "base/check.h"
#include "base/test/gmock_callback_support.h"
#include "base/test/task_environment.h"
#include "media/base/audio_decoder_config.h"
#include "media/base/media_util.h"
#include "media/base/mock_filters.h"
#include "media/base/renderer.h"
#include "media/base/test_helpers.h"
#include "media/base/video_decoder_config.h"
#include "media/remoting/mock_receiver_controller.h"
#include "media/remoting/proto_enum_utils.h"
#include "media/remoting/proto_utils.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/abseil-cpp/absl/types/optional.h"

using base::test::RunOnceCallback;
using openscreen::cast::RpcMessenger;
using testing::_;
using testing::AtLeast;
using testing::NiceMock;
using testing::StrictMock;

namespace media {
namespace remoting {

class MockSender {
 public:
  MockSender(RpcMessenger* rpc_messenger, int remote_handle)
      : rpc_messenger_(rpc_messenger),
        rpc_handle_(rpc_messenger->GetUniqueHandle()),
        remote_handle_(remote_handle) {
    rpc_messenger_->RegisterMessageReceiverCallback(
        rpc_handle_, [this](std::unique_ptr<openscreen::cast::RpcMessage> rpc) {
          this->OnReceivedRpc(std::move(rpc));
        });
  }

  MOCK_METHOD(void, AcquireRendererDone, ());
  MOCK_METHOD(void, InitializeCallback, (bool));
  MOCK_METHOD(void, FlushUntilCallback, ());
  MOCK_METHOD(void, OnTimeUpdate, (int64_t, int64_t));
  MOCK_METHOD(void, OnBufferingStateChange, (BufferingState));
  MOCK_METHOD(void, OnEnded, ());
  MOCK_METHOD(void, OnFatalError, ());
  MOCK_METHOD(void, OnAudioConfigChange, (AudioDecoderConfig));
  MOCK_METHOD(void, OnVideoConfigChange, (VideoDecoderConfig));
  MOCK_METHOD(void, OnVideoNaturalSizeChange, (gfx::Size));
  MOCK_METHOD(void, OnVideoOpacityChange, (bool));
  MOCK_METHOD(void, OnStatisticsUpdate, (PipelineStatistics));
  MOCK_METHOD(void, OnWaiting, ());

  void OnReceivedRpc(std::unique_ptr<openscreen::cast::RpcMessage> message) {
    DCHECK(message);
    switch (message->proc()) {
      case openscreen::cast::RpcMessage::RPC_ACQUIRE_RENDERER_DONE:
        AcquireRendererDone();
        break;
      case openscreen::cast::RpcMessage::RPC_R_INITIALIZE_CALLBACK:
        InitializeCallback(message->boolean_value());
        break;
      case openscreen::cast::RpcMessage::RPC_R_FLUSHUNTIL_CALLBACK:
        FlushUntilCallback();
        break;
      case openscreen::cast::RpcMessage::RPC_RC_ONTIMEUPDATE: {
        DCHECK(message->has_rendererclient_ontimeupdate_rpc());
        const int64_t time_usec =
            message->rendererclient_ontimeupdate_rpc().time_usec();
        const int64_t max_time_usec =
            message->rendererclient_ontimeupdate_rpc().max_time_usec();
        OnTimeUpdate(time_usec, max_time_usec);
        break;
      }
      case openscreen::cast::RpcMessage::RPC_RC_ONBUFFERINGSTATECHANGE: {
        absl::optional<BufferingState> state = ToMediaBufferingState(
            message->rendererclient_onbufferingstatechange_rpc().state());
        if (state.has_value())
          OnBufferingStateChange(state.value());
        break;
      }
      case openscreen::cast::RpcMessage::RPC_RC_ONENDED:
        OnEnded();
        break;
      case openscreen::cast::RpcMessage::RPC_RC_ONERROR:
        OnFatalError();
        break;
      case openscreen::cast::RpcMessage::RPC_RC_ONAUDIOCONFIGCHANGE: {
        DCHECK(message->has_rendererclient_onaudioconfigchange_rpc());
        const auto* audio_config_message =
            message->mutable_rendererclient_onaudioconfigchange_rpc();
        const openscreen::cast::AudioDecoderConfig pb_audio_config =
            audio_config_message->audio_decoder_config();
        AudioDecoderConfig out_audio_config;
        ConvertProtoToAudioDecoderConfig(pb_audio_config, &out_audio_config);
        DCHECK(out_audio_config.IsValidConfig());
        OnAudioConfigChange(out_audio_config);
        break;
      }
      case openscreen::cast::RpcMessage::RPC_RC_ONVIDEOCONFIGCHANGE: {
        DCHECK(message->has_rendererclient_onvideoconfigchange_rpc());
        const auto* video_config_message =
            message->mutable_rendererclient_onvideoconfigchange_rpc();
        const openscreen::cast::VideoDecoderConfig pb_video_config =
            video_config_message->video_decoder_config();
        VideoDecoderConfig out_video_config;
        ConvertProtoToVideoDecoderConfig(pb_video_config, &out_video_config);
        DCHECK(out_video_config.IsValidConfig());

        OnVideoConfigChange(out_video_config);
        break;
      }
      case openscreen::cast::RpcMessage::RPC_RC_ONVIDEONATURALSIZECHANGE: {
        DCHECK(message->has_rendererclient_onvideonatualsizechange_rpc());

        gfx::Size size(
            message->rendererclient_onvideonatualsizechange_rpc().width(),
            message->rendererclient_onvideonatualsizechange_rpc().height());
        OnVideoNaturalSizeChange(size);
        break;
      }
      case openscreen::cast::RpcMessage::RPC_RC_ONVIDEOOPACITYCHANGE:
        OnVideoOpacityChange(message->boolean_value());
        break;
      case openscreen::cast::RpcMessage::RPC_RC_ONSTATISTICSUPDATE: {
        DCHECK(message->has_rendererclient_onstatisticsupdate_rpc());
        auto rpc_message = message->rendererclient_onstatisticsupdate_rpc();
        PipelineStatistics statistics;
        statistics.audio_bytes_decoded = rpc_message.audio_bytes_decoded();
        statistics.video_bytes_decoded = rpc_message.video_bytes_decoded();
        statistics.video_frames_decoded = rpc_message.video_frames_decoded();
        statistics.video_frames_dropped = rpc_message.video_frames_dropped();
        statistics.audio_memory_usage = rpc_message.audio_memory_usage();
        statistics.video_memory_usage = rpc_message.video_memory_usage();
        OnStatisticsUpdate(statistics);
        break;
      }

      default:
        VLOG(1) << "Unknown RPC: " << message->proc();
    }
  }

  void SendRpcAcquireRenderer() {
    openscreen::cast::RpcMessage rpc;
    rpc.set_handle(RpcMessenger::kAcquireRendererHandle);
    rpc.set_proc(openscreen::cast::RpcMessage::RPC_ACQUIRE_RENDERER);
    rpc.set_integer_value(rpc_handle_);
    rpc_messenger_->SendMessageToRemote(rpc);
  }

  void SendRpcInitialize() {
    openscreen::cast::RpcMessage rpc;
    rpc.set_handle(remote_handle_);
    rpc.set_proc(openscreen::cast::RpcMessage::RPC_R_INITIALIZE);
    rpc_messenger_->SendMessageToRemote(rpc);
  }

  void SendRpcSetPlaybackRate(double playback_rate) {
    openscreen::cast::RpcMessage rpc;
    rpc.set_handle(remote_handle_);
    rpc.set_proc(openscreen::cast::RpcMessage::RPC_R_SETPLAYBACKRATE);
    rpc.set_double_value(playback_rate);
    rpc_messenger_->SendMessageToRemote(rpc);
  }

  void SendRpcFlushUntil(uint32_t audio_count, uint32_t video_count) {
    openscreen::cast::RpcMessage rpc;
    rpc.set_handle(remote_handle_);
    rpc.set_proc(openscreen::cast::RpcMessage::RPC_R_FLUSHUNTIL);
    openscreen::cast::RendererFlushUntil* message =
        rpc.mutable_renderer_flushuntil_rpc();
    message->set_audio_count(audio_count);
    message->set_video_count(video_count);
    message->set_callback_handle(rpc_handle_);
    rpc_messenger_->SendMessageToRemote(rpc);
  }

  void SendRpcStartPlayingFrom(base::TimeDelta time) {
    openscreen::cast::RpcMessage rpc;
    rpc.set_handle(remote_handle_);
    rpc.set_proc(openscreen::cast::RpcMessage::RPC_R_STARTPLAYINGFROM);
    rpc.set_integer64_value(time.InMicroseconds());
    rpc_messenger_->SendMessageToRemote(rpc);
  }

  void SendRpcSetVolume(float volume) {
    openscreen::cast::RpcMessage rpc;
    rpc.set_handle(remote_handle_);
    rpc.set_proc(openscreen::cast::RpcMessage::RPC_R_SETVOLUME);
    rpc.set_double_value(volume);
    rpc_messenger_->SendMessageToRemote(rpc);
  }

 private:
  RpcMessenger* const rpc_messenger_;
  const int rpc_handle_;
  const int remote_handle_;
};

class ReceiverTest : public ::testing::Test {
 public:
  ReceiverTest() = default;

  void SetUp() override {
    mock_controller_ = MockReceiverController::GetInstance();
    mock_controller_->Initialize(
        mock_controller_->mock_remotee()->BindNewPipeAndPassRemote());
    mock_remotee_ = mock_controller_->mock_remotee();

    rpc_messenger_ = mock_controller_->rpc_messenger();
    receiver_renderer_handle_ = rpc_messenger_->GetUniqueHandle();

    mock_sender_ = std::make_unique<StrictMock<MockSender>>(
        rpc_messenger_, receiver_renderer_handle_);

    rpc_messenger_->RegisterMessageReceiverCallback(
        RpcMessenger::kAcquireRendererHandle,
        [ptr = weak_factory_.GetWeakPtr()](
            std::unique_ptr<openscreen::cast::RpcMessage> message) {
          if (ptr) {
            ptr->OnReceivedRpc(std::move(message));
          }
        });
  }

  void TearDown() override {
    rpc_messenger_->UnregisterMessageReceiverCallback(
        RpcMessenger::kAcquireRendererHandle);
  }

  void OnReceivedRpc(std::unique_ptr<openscreen::cast::RpcMessage> message) {
    DCHECK(message);
    EXPECT_EQ(message->proc(),
              openscreen::cast::RpcMessage::RPC_ACQUIRE_RENDERER);
    OnAcquireRenderer(std::move(message));
  }

  void OnAcquireRenderer(
      std::unique_ptr<openscreen::cast::RpcMessage> message) {
    DCHECK(message->has_integer_value());
    DCHECK(message->integer_value() != RpcMessenger::kInvalidHandle);

    if (sender_renderer_handle_ == RpcMessenger::kInvalidHandle) {
      sender_renderer_handle_ = message->integer_value();
      SetRemoteHandle();
    }
  }

  void OnAcquireRendererDone(int receiver_renderer_handle) {
    DVLOG(3) << __func__
             << ": Issues RPC_ACQUIRE_RENDERER_DONE RPC message. remote_handle="
             << sender_renderer_handle_
             << " rpc_handle=" << receiver_renderer_handle;
    openscreen::cast::RpcMessage rpc;
    rpc.set_handle(sender_renderer_handle_);
    rpc.set_proc(openscreen::cast::RpcMessage::RPC_ACQUIRE_RENDERER_DONE);
    rpc.set_integer_value(receiver_renderer_handle);
    rpc_messenger_->SendMessageToRemote(rpc);
  }

  void CreateReceiver() {
    auto renderer = std::make_unique<NiceMock<MockRenderer>>();
    mock_renderer_ = renderer.get();
    receiver_ = std::make_unique<Receiver>(
        receiver_renderer_handle_, sender_renderer_handle_, mock_controller_,
        base::ThreadTaskRunnerHandle::Get(), std::move(renderer),
        base::BindOnce(&ReceiverTest::OnAcquireRendererDone,
                       weak_factory_.GetWeakPtr()));
  }

  void SetRemoteHandle() {
    if (!receiver_)
      return;
    receiver_->SetRemoteHandle(sender_renderer_handle_);
  }

  void InitializeReceiver() {
    receiver_->Initialize(&mock_media_resource_, nullptr,
                          base::BindOnce(&ReceiverTest::OnRendererInitialized,
                                         weak_factory_.GetWeakPtr()));
  }

  MOCK_METHOD(void, OnRendererInitialized, (PipelineStatus));

  base::test::TaskEnvironment task_environment_;

  int sender_renderer_handle_ = RpcMessenger::kInvalidHandle;
  int receiver_renderer_handle_ = RpcMessenger::kInvalidHandle;

  MockMediaResource mock_media_resource_;
  MockRenderer* mock_renderer_ = nullptr;
  std::unique_ptr<MockSender> mock_sender_;

  RpcMessenger* rpc_messenger_ = nullptr;
  MockRemotee* mock_remotee_;
  MockReceiverController* mock_controller_ = nullptr;
  std::unique_ptr<Receiver> receiver_;

  base::WeakPtrFactory<ReceiverTest> weak_factory_{this};
};

TEST_F(ReceiverTest, AcquireRendererBeforeCreateReceiver) {
  mock_sender_->SendRpcAcquireRenderer();
  EXPECT_CALL(*mock_sender_, AcquireRendererDone()).Times(1);
  CreateReceiver();
  task_environment_.RunUntilIdle();
}

TEST_F(ReceiverTest, AcquireRendererAfterCreateReceiver) {
  CreateReceiver();
  EXPECT_CALL(*mock_sender_, AcquireRendererDone()).Times(1);
  mock_sender_->SendRpcAcquireRenderer();
  task_environment_.RunUntilIdle();
}

// |Receiver::Initialize| will be called by the local pipeline, and the
// |Receiver::RpcInitialize| will be called once it received the
// RPC_R_INITIALIZE messages, so these two initialization functions are possible
// to be called in difference orders.
//
// Call |Receiver::Initialize| first, then send RPC_R_INITIALIZE.
TEST_F(ReceiverTest, InitializeBeforeRpcInitialize) {
  EXPECT_CALL(*mock_sender_, AcquireRendererDone()).Times(1);
  mock_sender_->SendRpcAcquireRenderer();
  CreateReceiver();

  EXPECT_CALL(*mock_renderer_,
              OnInitialize(&mock_media_resource_, receiver_.get(), _))
      .WillOnce(RunOnceCallback<2>(PipelineStatus::PIPELINE_OK));
  EXPECT_CALL(*this, OnRendererInitialized(PipelineStatus::PIPELINE_OK))
      .Times(1);
  EXPECT_CALL(*mock_sender_, InitializeCallback(true)).Times(1);

  InitializeReceiver();
  mock_sender_->SendRpcInitialize();
  task_environment_.RunUntilIdle();
}

// Send RPC_R_INITIALIZE first, then call |Receiver::Initialize|.
TEST_F(ReceiverTest, InitializeAfterRpcInitialize) {
  EXPECT_CALL(*mock_sender_, AcquireRendererDone()).Times(1);
  mock_sender_->SendRpcAcquireRenderer();
  CreateReceiver();

  EXPECT_CALL(*mock_renderer_,
              OnInitialize(&mock_media_resource_, receiver_.get(), _))
      .WillOnce(RunOnceCallback<2>(PipelineStatus::PIPELINE_OK));
  EXPECT_CALL(*this, OnRendererInitialized(PipelineStatus::PIPELINE_OK))
      .Times(1);
  EXPECT_CALL(*mock_sender_, InitializeCallback(true)).Times(1);

  mock_sender_->SendRpcInitialize();
  InitializeReceiver();
  task_environment_.RunUntilIdle();
}

TEST_F(ReceiverTest, RpcRendererMessages) {
  EXPECT_CALL(*mock_sender_, AcquireRendererDone()).Times(1);
  mock_sender_->SendRpcAcquireRenderer();
  CreateReceiver();
  mock_sender_->SendRpcInitialize();
  InitializeReceiver();
  task_environment_.RunUntilIdle();

  // SetVolume
  const float volume = 0.5;
  EXPECT_CALL(*mock_renderer_, SetVolume(volume)).Times(1);
  mock_sender_->SendRpcSetVolume(volume);
  task_environment_.RunUntilIdle();

  EXPECT_CALL(*mock_sender_, OnTimeUpdate(_, _)).Times(AtLeast(1));

  // SetPlaybackRate
  const double playback_rate = 1.2;
  EXPECT_CALL(*mock_renderer_, SetPlaybackRate(playback_rate)).Times(1);
  mock_sender_->SendRpcSetPlaybackRate(playback_rate);
  task_environment_.RunUntilIdle();

  // Flush
  const uint32_t flush_audio_count = 10;
  const uint32_t flush_video_count = 20;
  EXPECT_CALL(*mock_renderer_, OnFlush(_)).WillOnce(RunOnceCallback<0>());
  EXPECT_CALL(*mock_sender_, FlushUntilCallback()).Times(1);
  mock_sender_->SendRpcFlushUntil(flush_audio_count, flush_video_count);
  task_environment_.RunUntilIdle();
  EXPECT_EQ(flush_audio_count, mock_remotee_->flush_audio_count());
  EXPECT_EQ(flush_video_count, mock_remotee_->flush_video_count());

  // StartPlayingFrom
  const base::TimeDelta time = base::Seconds(100);
  EXPECT_CALL(*mock_renderer_, StartPlayingFrom(time)).Times(1);
  mock_sender_->SendRpcStartPlayingFrom(time);
  task_environment_.RunUntilIdle();
}

TEST_F(ReceiverTest, RendererClientInterface) {
  EXPECT_CALL(*mock_sender_, AcquireRendererDone()).Times(1);
  mock_sender_->SendRpcAcquireRenderer();
  CreateReceiver();
  mock_sender_->SendRpcInitialize();
  InitializeReceiver();
  task_environment_.RunUntilIdle();

  // OnBufferingStateChange
  EXPECT_CALL(*mock_sender_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH))
      .Times(1);
  receiver_->OnBufferingStateChange(BUFFERING_HAVE_ENOUGH,
                                    BUFFERING_CHANGE_REASON_UNKNOWN);
  task_environment_.RunUntilIdle();

  // OnEnded
  EXPECT_CALL(*mock_sender_, OnEnded()).Times(1);
  receiver_->OnEnded();
  task_environment_.RunUntilIdle();

  // OnError
  EXPECT_CALL(*mock_sender_, OnFatalError()).Times(1);
  receiver_->OnError(PipelineStatus::AUDIO_RENDERER_ERROR);
  task_environment_.RunUntilIdle();

  // OnAudioConfigChange
  const auto kNewAudioConfig = TestAudioConfig::Normal();
  EXPECT_CALL(*mock_sender_,
              OnAudioConfigChange(DecoderConfigEq(kNewAudioConfig)))
      .Times(1);
  receiver_->OnAudioConfigChange(kNewAudioConfig);
  task_environment_.RunUntilIdle();

  // OnVideoConfigChange
  const auto kNewVideoConfig = TestVideoConfig::Normal();
  EXPECT_CALL(*mock_sender_,
              OnVideoConfigChange(DecoderConfigEq(kNewVideoConfig)))
      .Times(1);
  receiver_->OnVideoConfigChange(kNewVideoConfig);
  task_environment_.RunUntilIdle();

  // OnVideoNaturalSizeChange
  const gfx::Size size(100, 200);
  EXPECT_CALL(*mock_sender_, OnVideoNaturalSizeChange(size)).Times(1);
  receiver_->OnVideoNaturalSizeChange(size);
  task_environment_.RunUntilIdle();
  EXPECT_EQ(size, mock_remotee_->changed_size());

  // OnVideoOpacityChange
  const bool opaque = true;
  EXPECT_CALL(*mock_sender_, OnVideoOpacityChange(opaque)).Times(1);
  receiver_->OnVideoOpacityChange(opaque);
  task_environment_.RunUntilIdle();

  // OnStatisticsUpdate
  PipelineStatistics statistics;
  statistics.audio_bytes_decoded = 100;
  statistics.video_bytes_decoded = 200;
  statistics.video_frames_decoded = 300;
  statistics.video_frames_dropped = 400;
  statistics.audio_memory_usage = 500;
  statistics.video_memory_usage = 600;
  EXPECT_CALL(*mock_sender_, OnStatisticsUpdate(statistics)).Times(1);
  receiver_->OnStatisticsUpdate(statistics);
  task_environment_.RunUntilIdle();
}

}  // namespace remoting
}  // namespace media
