// Copyright 2014 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 "content/renderer/queue_message_swap_promise.h"

#include <stddef.h>

#include <memory>
#include <vector>

#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/test/scoped_task_environment.h"
#include "cc/trees/swap_promise.h"
#include "content/common/render_frame_metadata.mojom.h"
#include "content/common/widget_messages.h"
#include "content/renderer/compositor/layer_tree_view.h"
#include "content/renderer/frame_swap_message_queue.h"
#include "content/renderer/render_widget.h"
#include "content/test/mock_render_process.h"
#include "ipc/ipc_message.h"
#include "ipc/ipc_sync_message_filter.h"
#include "ipc/ipc_test_sink.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace content {

class TestSyncMessageFilter : public IPC::SyncMessageFilter {
 public:
  TestSyncMessageFilter() : IPC::SyncMessageFilter(nullptr) {}

  bool Send(IPC::Message* message) override {
    if (message->type() == WidgetHostMsg_FrameSwapMessages::ID) {
      WidgetHostMsg_FrameSwapMessages::Param param;
      WidgetHostMsg_FrameSwapMessages::Read(message, &param);
      std::vector<IPC::Message> messages = std::get<1>(param);
      last_swap_messages_.clear();
      for (const IPC::Message& message : messages) {
        last_swap_messages_.push_back(std::make_unique<IPC::Message>(message));
      }
      delete message;
    } else {
      direct_send_messages_.push_back(base::WrapUnique(message));
    }
    return true;
  }

  std::vector<std::unique_ptr<IPC::Message>>& last_swap_messages() {
    return last_swap_messages_;
  }

  const std::vector<std::unique_ptr<IPC::Message>>& direct_send_messages() {
    return direct_send_messages_;
  }

 private:
  ~TestSyncMessageFilter() override {}

  std::vector<std::unique_ptr<IPC::Message>> direct_send_messages_;
  std::vector<std::unique_ptr<IPC::Message>> last_swap_messages_;

  DISALLOW_COPY_AND_ASSIGN(TestSyncMessageFilter);
};

class QueueMessageSwapPromiseTest : public testing::Test {
 public:
  QueueMessageSwapPromiseTest()
      : frame_swap_message_queue_(new FrameSwapMessageQueue(0)),
        sync_message_filter_(new TestSyncMessageFilter()) {}

  ~QueueMessageSwapPromiseTest() override {}

  std::unique_ptr<cc::SwapPromise> QueueMessageImpl(IPC::Message* msg,
                                                    int source_frame_number) {
    return RenderWidget::QueueMessageImpl(msg, frame_swap_message_queue_.get(),
                                          sync_message_filter_,
                                          source_frame_number);
  }

  const std::vector<std::unique_ptr<IPC::Message>>& DirectSendMessages() {
    return sync_message_filter_->direct_send_messages();
  }

  std::vector<std::unique_ptr<IPC::Message>>& LastSwapMessages() {
    return sync_message_filter_->last_swap_messages();
  }

  std::vector<std::unique_ptr<IPC::Message>>& NextSwapMessages() {
    next_swap_messages_.clear();
    std::unique_ptr<FrameSwapMessageQueue::SendMessageScope>
        send_message_scope =
            frame_swap_message_queue_->AcquireSendMessageScope();
    frame_swap_message_queue_->DrainMessages(&next_swap_messages_);
    return next_swap_messages_;
  }

  bool ContainsMessage(
      const std::vector<std::unique_ptr<IPC::Message>>& messages,
      const IPC::Message& message) {
    if (messages.empty())
      return false;
    for (const auto& msg : messages) {
      if (msg->type() == message.type())
        return true;
    }
    return false;
  }

  bool LastSwapHasMessage(const IPC::Message& message) {
    return ContainsMessage(LastSwapMessages(), message);
  }

  bool NextSwapHasMessage(const IPC::Message& message) {
    return ContainsMessage(NextSwapMessages(), message);
  }

  void QueueMessages(int source_frame_numbers[], size_t count) {
    for (size_t i = 0; i < count; ++i) {
      messages_.push_back(
          IPC::Message(0, i + 1, IPC::Message::PRIORITY_NORMAL));
      promises_.push_back(QueueMessageImpl(new IPC::Message(messages_[i]),
                                           source_frame_numbers[i]));
    }
  }

  void CleanupPromises() {
    for (const auto& promise : promises_) {
      if (promise.get()) {
        promise->DidActivate();
        promise->WillSwap(&dummy_metadata_);
        promise->DidSwap();
      }
    }
  }

 protected:
  void VisualStateSwapPromiseDidNotSwap(
      cc::SwapPromise::DidNotSwapReason reason);

  base::test::ScopedTaskEnvironment scoped_task_environment_;
  scoped_refptr<FrameSwapMessageQueue> frame_swap_message_queue_;
  scoped_refptr<TestSyncMessageFilter> sync_message_filter_;
  std::vector<IPC::Message> messages_;
  std::vector<std::unique_ptr<cc::SwapPromise>> promises_;
  viz::CompositorFrameMetadata dummy_metadata_;
  cc::RenderFrameMetadata dummy_render_frame_metadata_;

 private:
  std::vector<std::unique_ptr<IPC::Message>> next_swap_messages_;

  DISALLOW_COPY_AND_ASSIGN(QueueMessageSwapPromiseTest);
};

TEST_F(QueueMessageSwapPromiseTest, NextSwapPolicySchedulesMessageForNextSwap) {
  int source_frame_numbers[] = {1};
  QueueMessages(source_frame_numbers, base::size(source_frame_numbers));

  ASSERT_TRUE(promises_[0].get());
  promises_[0]->DidActivate();
  promises_[0]->WillSwap(&dummy_metadata_);
  promises_[0]->DidSwap();

  EXPECT_TRUE(DirectSendMessages().empty());
  EXPECT_TRUE(frame_swap_message_queue_->Empty());
  EXPECT_TRUE(LastSwapHasMessage(messages_[0]));
}

TEST_F(QueueMessageSwapPromiseTest, NextSwapPolicyNeedsAtMostOnePromise) {
  int source_frame_numbers[] = {1, 1};
  QueueMessages(source_frame_numbers, base::size(source_frame_numbers));

  ASSERT_TRUE(promises_[0].get());
  ASSERT_FALSE(promises_[1].get());

  CleanupPromises();
}

TEST_F(QueueMessageSwapPromiseTest, NextSwapPolicySendsMessageOnNoUpdate) {
  int source_frame_numbers[] = {1};
  QueueMessages(source_frame_numbers, base::size(source_frame_numbers));

  promises_[0]->DidNotSwap(cc::SwapPromise::COMMIT_NO_UPDATE);
  EXPECT_TRUE(ContainsMessage(DirectSendMessages(), messages_[0]));
  EXPECT_TRUE(LastSwapMessages().empty());
  EXPECT_TRUE(frame_swap_message_queue_->Empty());
}

TEST_F(QueueMessageSwapPromiseTest, NextSwapPolicySendsMessageOnSwapFails) {
  int source_frame_numbers[] = {1};
  QueueMessages(source_frame_numbers, base::size(source_frame_numbers));

  promises_[0]->DidNotSwap(cc::SwapPromise::SWAP_FAILS);
  EXPECT_TRUE(ContainsMessage(DirectSendMessages(), messages_[0]));
  EXPECT_TRUE(LastSwapMessages().empty());
  EXPECT_TRUE(frame_swap_message_queue_->Empty());
}

TEST_F(QueueMessageSwapPromiseTest,
       NextActivatePolicyRetainsMessageOnCommitFails) {
  int source_frame_numbers[] = {1};
  QueueMessages(source_frame_numbers, base::size(source_frame_numbers));

  promises_[0]->DidNotSwap(cc::SwapPromise::COMMIT_FAILS);
  EXPECT_TRUE(DirectSendMessages().empty());
  EXPECT_TRUE(LastSwapMessages().empty());
  EXPECT_FALSE(frame_swap_message_queue_->Empty());
  frame_swap_message_queue_->DidActivate(2);
  EXPECT_TRUE(NextSwapHasMessage(messages_[0]));
}

TEST_F(QueueMessageSwapPromiseTest,
       VisualStateQueuesMessageWhenCommitRequested) {
  int source_frame_numbers[] = {1};
  QueueMessages(source_frame_numbers, base::size(source_frame_numbers));

  ASSERT_TRUE(promises_[0].get());
  EXPECT_TRUE(DirectSendMessages().empty());
  EXPECT_FALSE(frame_swap_message_queue_->Empty());
  EXPECT_TRUE(NextSwapMessages().empty());

  CleanupPromises();
}

TEST_F(QueueMessageSwapPromiseTest,
       VisualStateQueuesMessageWhenOtherMessageAlreadyQueued) {
  int source_frame_numbers[] = {1, 1};
  QueueMessages(source_frame_numbers, base::size(source_frame_numbers));

  EXPECT_TRUE(DirectSendMessages().empty());
  EXPECT_FALSE(frame_swap_message_queue_->Empty());
  EXPECT_FALSE(NextSwapHasMessage(messages_[1]));

  CleanupPromises();
}

TEST_F(QueueMessageSwapPromiseTest, VisualStateSwapPromiseDidActivate) {
  int source_frame_numbers[] = {1, 1, 2};
  QueueMessages(source_frame_numbers, base::size(source_frame_numbers));

  promises_[0]->DidActivate();
  promises_[0]->WillSwap(&dummy_metadata_);
  promises_[0]->DidSwap();
  ASSERT_FALSE(promises_[1].get());
  std::vector<std::unique_ptr<IPC::Message>> messages;
  messages.swap(LastSwapMessages());
  EXPECT_EQ(2u, messages.size());
  EXPECT_TRUE(ContainsMessage(messages, messages_[0]));
  EXPECT_TRUE(ContainsMessage(messages, messages_[1]));
  EXPECT_FALSE(ContainsMessage(messages, messages_[2]));

  promises_[2]->DidActivate();
  promises_[2]->DidNotSwap(cc::SwapPromise::SWAP_FAILS);
  messages.swap(NextSwapMessages());
  EXPECT_TRUE(messages.empty());

  EXPECT_EQ(1u, DirectSendMessages().size());
  EXPECT_TRUE(ContainsMessage(DirectSendMessages(), messages_[2]));

  EXPECT_TRUE(NextSwapMessages().empty());
  EXPECT_TRUE(frame_swap_message_queue_->Empty());
}

void QueueMessageSwapPromiseTest::VisualStateSwapPromiseDidNotSwap(
    cc::SwapPromise::DidNotSwapReason reason) {
  int source_frame_numbers[] = {1, 1, 2};
  QueueMessages(source_frame_numbers, base::size(source_frame_numbers));

  // If we fail to swap with COMMIT_FAILS or ACTIVATE_FAILS, then
  // messages are delivered by the RenderFrameHostImpl destructor,
  // rather than directly by the swap promise.
  bool msg_delivered = reason != cc::SwapPromise::COMMIT_FAILS &&
                       reason != cc::SwapPromise::ACTIVATION_FAILS;

  promises_[0]->DidNotSwap(reason);
  ASSERT_FALSE(promises_[1].get());
  EXPECT_TRUE(NextSwapMessages().empty());
  EXPECT_EQ(msg_delivered, ContainsMessage(DirectSendMessages(), messages_[0]));
  EXPECT_EQ(msg_delivered, ContainsMessage(DirectSendMessages(), messages_[1]));
  EXPECT_FALSE(ContainsMessage(DirectSendMessages(), messages_[2]));

  promises_[2]->DidNotSwap(reason);
  EXPECT_TRUE(NextSwapMessages().empty());
  EXPECT_EQ(msg_delivered, ContainsMessage(DirectSendMessages(), messages_[2]));

  EXPECT_TRUE(NextSwapMessages().empty());
  EXPECT_EQ(msg_delivered, frame_swap_message_queue_->Empty());
}

TEST_F(QueueMessageSwapPromiseTest, VisualStateSwapPromiseDidNotSwapNoUpdate) {
  VisualStateSwapPromiseDidNotSwap(cc::SwapPromise::COMMIT_NO_UPDATE);
}

TEST_F(QueueMessageSwapPromiseTest,
       VisualStateSwapPromiseDidNotSwapCommitFails) {
  VisualStateSwapPromiseDidNotSwap(cc::SwapPromise::COMMIT_FAILS);
}

TEST_F(QueueMessageSwapPromiseTest, VisualStateSwapPromiseDidNotSwapSwapFails) {
  VisualStateSwapPromiseDidNotSwap(cc::SwapPromise::SWAP_FAILS);
}

TEST_F(QueueMessageSwapPromiseTest,
       VisualStateSwapPromiseDidNotSwapActivationFails) {
  VisualStateSwapPromiseDidNotSwap(cc::SwapPromise::ACTIVATION_FAILS);
}

}  // namespace content
