// 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 "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/memory/ptr_util.h"
#include "base/threading/thread_task_runner_handle.h"
#include "media/remoting/proto_utils.h"
#include "media/remoting/shared_session.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace media {
namespace remoting {

FakeRemotingDataStreamSender::FakeRemotingDataStreamSender(
    mojom::RemotingDataStreamSenderRequest request,
    mojo::ScopedDataPipeConsumerHandle consumer_handle)
    : binding_(this, std::move(request)),
      consumer_handle_(std::move(consumer_handle)),
      consume_data_chunk_count_(0),
      send_frame_count_(0),
      cancel_in_flight_count_(0) {}

FakeRemotingDataStreamSender::~FakeRemotingDataStreamSender() = default;

void FakeRemotingDataStreamSender::ResetHistory() {
  consume_data_chunk_count_ = 0;
  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;
  }

  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;
}

void FakeRemotingDataStreamSender::ConsumeDataChunk(
    uint32_t offset,
    uint32_t size,
    uint32_t total_payload_size) {
  next_frame_data_.resize(total_payload_size);
  MojoResult result = mojo::ReadDataRaw(consumer_handle_.get(),
                                        next_frame_data_.data() + offset, &size,
                                        MOJO_READ_DATA_FLAG_ALL_OR_NONE);
  CHECK(result == MOJO_RESULT_OK);
  ++consume_data_chunk_count_;
}

void FakeRemotingDataStreamSender::SendFrame() {
  ++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() {}

void FakeRemoter::Start() {
  if (start_will_fail_) {
    base::ThreadTaskRunnerHandle::Get()->PostTask(
        FROM_HERE,
        base::Bind(&FakeRemoter::StartFailed, weak_factory_.GetWeakPtr()));
  } else {
    base::ThreadTaskRunnerHandle::Get()->PostTask(
        FROM_HERE,
        base::Bind(&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::Bind(&FakeRemoter::Stopped, weak_factory_.GetWeakPtr(), reason));
}

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

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() {}

void FakeRemoterFactory::Create(mojom::RemotingSourcePtr source,
                                mojom::RemoterRequest request) {
  mojo::MakeStrongBinding(
      base::MakeUnique<FakeRemoter>(std::move(source), start_will_fail_),
      std::move(request));
}

// static
scoped_refptr<SharedSession> FakeRemoterFactory::CreateSharedSession(
    bool start_will_fail) {
  mojom::RemotingSourcePtr remoting_source;
  mojom::RemotingSourceRequest remoting_source_request(&remoting_source);
  mojom::RemoterPtr remoter;
  FakeRemoterFactory remoter_factory(start_will_fail);
  remoter_factory.Create(std::move(remoting_source),
                         mojo::MakeRequest(&remoter));
  return new SharedSession(std::move(remoting_source_request),
                           std::move(remoter));
}

}  // namespace remoting
}  // namespace media
