// 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/bind_helpers.h"
#include "base/callback.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/strong_binding.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(
    mojom::RemotingDataStreamSenderRequest request,
    mojo::ScopedDataPipeConsumerHandle consumer_handle)
    : binding_(this, std::move(request)),
      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(mojom::RemotingSourcePtr source, bool start_will_fail)
    : source_(std::move(source)),
      start_will_fail_(start_will_fail),
      weak_factory_(this) {}

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,
    mojom::RemotingDataStreamSenderRequest audio_sender_request,
    mojom::RemotingDataStreamSenderRequest video_sender_request) {
  if (audio_pipe.is_valid()) {
    VLOG(2) << "Has audio";
    audio_stream_sender_.reset(new FakeRemotingDataStreamSender(
        std::move(audio_sender_request), std::move(audio_pipe)));
  }

  if (video_pipe.is_valid()) {
    VLOG(2) << "Has video";
    video_stream_sender_.reset(new FakeRemotingDataStreamSender(
        std::move(video_sender_request), 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(mojom::RemotingSourcePtr source,
                                mojom::RemoterRequest request) {
  mojo::MakeStrongBinding(
      std::make_unique<FakeRemoter>(std::move(source), start_will_fail_),
      std::move(request));
}

// static
std::unique_ptr<RendererController> FakeRemoterFactory::CreateController(
    bool start_will_fail) {
  mojom::RemotingSourcePtr remoting_source;
  auto remoting_source_request = mojo::MakeRequest(&remoting_source);
  mojom::RemoterPtr remoter;
  FakeRemoterFactory remoter_factory(start_will_fail);
  remoter_factory.Create(std::move(remoting_source),
                         mojo::MakeRequest(&remoter));
  return std::make_unique<RendererController>(
      std::move(remoting_source_request), std::move(remoter));
}

}  // namespace remoting
}  // namespace media
