// Copyright 2016 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/fake_remoter.h"

#include <memory>

#include "base/bind.h"
#include "base/callback.h"
#include "base/callback_helpers.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/buildflag.h"
#include "media/media_buildflags.h"
#include "media/remoting/renderer_controller.h"
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
#include "testing/gtest/include/gtest/gtest.h"

#if BUILDFLAG(ENABLE_MEDIA_REMOTING_RPC)
#include "media/remoting/proto_utils.h"  // nogncheck
#endif

namespace media {
namespace remoting {

FakeRemotingDataStreamSender::FakeRemotingDataStreamSender(
    mojo::PendingReceiver<mojom::RemotingDataStreamSender> stream_sender,
    mojo::ScopedDataPipeConsumerHandle consumer_handle)
    : receiver_(this, std::move(stream_sender)),
      data_pipe_reader_(std::move(consumer_handle)),
      send_frame_count_(0),
      cancel_in_flight_count_(0) {}

FakeRemotingDataStreamSender::~FakeRemotingDataStreamSender() = default;

void FakeRemotingDataStreamSender::ResetHistory() {
  send_frame_count_ = 0;
  cancel_in_flight_count_ = 0;
  next_frame_data_.resize(0);
  received_frame_list.clear();
}

bool FakeRemotingDataStreamSender::ValidateFrameBuffer(size_t index,
                                                       size_t size,
                                                       bool key_frame,
                                                       int pts_ms) {
  if (index >= received_frame_list.size()) {
    VLOG(1) << "There is no such frame";
    return false;
  }

#if BUILDFLAG(ENABLE_MEDIA_REMOTING_RPC)
  const std::vector<uint8_t>& data = received_frame_list[index];
  scoped_refptr<DecoderBuffer> media_buffer =
      ByteArrayToDecoderBuffer(data.data(), data.size());

  // Checks if pts is correct or not
  if (media_buffer->timestamp().InMilliseconds() != pts_ms) {
    VLOG(1) << "Pts should be:" << pts_ms << "("
            << media_buffer->timestamp().InMilliseconds() << ")";
    return false;
  }

  // Checks if key frame is set correct or not
  if (media_buffer->is_key_frame() != key_frame) {
    VLOG(1) << "Key frame should be:" << key_frame << "("
            << media_buffer->is_key_frame() << ")";
    return false;
  }

  // Checks if frame buffer size is correct or not
  if (media_buffer->data_size() != size) {
    VLOG(1) << "Buffer size should be:" << size << "("
            << media_buffer->data_size() << ")";
    return false;
  }

  // Checks if frame buffer is correct or not.
  bool return_value = true;
  const uint8_t* buffer = media_buffer->data();
  for (size_t i = 0; i < media_buffer->data_size(); ++i) {
    uint32_t value = static_cast<uint32_t>(i & 0xFF);
    if (value != static_cast<uint32_t>(buffer[i])) {
      VLOG(1) << "buffer index: " << i << " should be "
              << static_cast<uint32_t>(value) << " ("
              << static_cast<uint32_t>(buffer[i]) << ")";
      return_value = false;
    }
  }
  return return_value;
#else
  return true;
#endif  // BUILDFLAG(ENABLE_MEDIA_REMOTING_RPC)
}

void FakeRemotingDataStreamSender::SendFrame(uint32_t frame_size) {
  next_frame_data_.resize(frame_size);
  data_pipe_reader_.Read(
      next_frame_data_.data(), frame_size,
      base::BindOnce(&FakeRemotingDataStreamSender::OnFrameRead,
                     base::Unretained(this)));
}

void FakeRemotingDataStreamSender::OnFrameRead(bool success) {
  EXPECT_TRUE(success);

  ++send_frame_count_;
  received_frame_list.push_back(std::move(next_frame_data_));
  EXPECT_EQ(send_frame_count_, received_frame_list.size());
}

void FakeRemotingDataStreamSender::CancelInFlightData() {
  ++cancel_in_flight_count_;
}

FakeRemoter::FakeRemoter(mojo::PendingRemote<mojom::RemotingSource> source,
                         bool start_will_fail)
    : source_(std::move(source)), start_will_fail_(start_will_fail) {}

FakeRemoter::~FakeRemoter() = default;

void FakeRemoter::Start() {
  if (start_will_fail_) {
    base::ThreadTaskRunnerHandle::Get()->PostTask(
        FROM_HERE,
        base::BindOnce(&FakeRemoter::StartFailed, weak_factory_.GetWeakPtr()));
  } else {
    base::ThreadTaskRunnerHandle::Get()->PostTask(
        FROM_HERE,
        base::BindOnce(&FakeRemoter::Started, weak_factory_.GetWeakPtr()));
  }
}

void FakeRemoter::StartDataStreams(
    mojo::ScopedDataPipeConsumerHandle audio_pipe,
    mojo::ScopedDataPipeConsumerHandle video_pipe,
    mojo::PendingReceiver<mojom::RemotingDataStreamSender> audio_sender,
    mojo::PendingReceiver<mojom::RemotingDataStreamSender> video_sender) {
  if (audio_pipe.is_valid()) {
    VLOG(2) << "Has audio";
    audio_stream_sender_ = std::make_unique<FakeRemotingDataStreamSender>(
        std::move(audio_sender), std::move(audio_pipe));
  }

  if (video_pipe.is_valid()) {
    VLOG(2) << "Has video";
    video_stream_sender_ = std::make_unique<FakeRemotingDataStreamSender>(
        std::move(video_sender), std::move(video_pipe));
  }
}

void FakeRemoter::Stop(mojom::RemotingStopReason reason) {
  base::ThreadTaskRunnerHandle::Get()->PostTask(
      FROM_HERE, base::BindOnce(&FakeRemoter::Stopped,
                                weak_factory_.GetWeakPtr(), reason));
}

void FakeRemoter::SendMessageToSink(const std::vector<uint8_t>& message) {}

void FakeRemoter::EstimateTransmissionCapacity(
    mojom::Remoter::EstimateTransmissionCapacityCallback callback) {
  std::move(callback).Run(10000000 / 8.0);
}

void FakeRemoter::Started() {
  source_->OnStarted();
}

void FakeRemoter::StartFailed() {
  source_->OnStartFailed(mojom::RemotingStartFailReason::ROUTE_TERMINATED);
}

void FakeRemoter::Stopped(mojom::RemotingStopReason reason) {
  source_->OnStopped(reason);
}

FakeRemoterFactory::FakeRemoterFactory(bool start_will_fail)
    : start_will_fail_(start_will_fail) {}

FakeRemoterFactory::~FakeRemoterFactory() = default;

void FakeRemoterFactory::Create(
    mojo::PendingRemote<mojom::RemotingSource> source,
    mojo::PendingReceiver<mojom::Remoter> receiver) {
  mojo::MakeSelfOwnedReceiver(
      std::make_unique<FakeRemoter>(std::move(source), start_will_fail_),
      std::move(receiver));
}

// static
std::unique_ptr<RendererController> FakeRemoterFactory::CreateController(
    bool start_will_fail) {
  mojo::PendingRemote<mojom::RemotingSource> remoting_source;
  auto remoting_source_receiver =
      remoting_source.InitWithNewPipeAndPassReceiver();
  mojo::PendingRemote<mojom::Remoter> remoter;
  FakeRemoterFactory remoter_factory(start_will_fail);
  remoter_factory.Create(std::move(remoting_source),
                         remoter.InitWithNewPipeAndPassReceiver());
  return std::make_unique<RendererController>(
      std::move(remoting_source_receiver), std::move(remoter));
}

}  // namespace remoting
}  // namespace media
