// 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 "content/browser/webrtc/webrtc_eventlog_host.h"

#include <tuple>

#include "base/files/file.h"
#include "base/files/file_util.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/common/media/peer_connection_tracker_messages.h"
#include "content/public/browser/browser_context.h"
#include "content/public/test/mock_render_process_host.h"
#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "testing/gtest/include/gtest/gtest.h"

#if defined(OS_WIN)
#define IntToStringType base::IntToString16
#else
#define IntToStringType base::IntToString
#endif

namespace content {

namespace {

// Get the expected Rtc eventlog file name. The name will be
// <temporary path>.<render process id>.<peer connection local id>
base::FilePath GetExpectedEventLogFileName(const base::FilePath& base_file,
                                           int render_process_id,
                                           int peer_connection_local_id) {
  return base_file.AddExtension(IntToStringType(render_process_id))
      .AddExtension(IntToStringType(peer_connection_local_id));
}

}  // namespace

class WebRtcEventlogHostTest : public testing::Test {
 public:
  WebRtcEventlogHostTest()
      : mock_render_process_host_(static_cast<MockRenderProcessHost*>(
            mock_render_process_factory_.CreateRenderProcessHost(
                &test_browser_context_))),
        render_id_(mock_render_process_host_->GetID()),
        event_log_host_(render_id_) {}
  TestBrowserThreadBundle thread_bundle_;
  MockRenderProcessHostFactory mock_render_process_factory_;
  TestBrowserContext test_browser_context_;
  std::unique_ptr<MockRenderProcessHost> mock_render_process_host_;
  const int render_id_;
  WebRTCEventLogHost event_log_host_;
  base::FilePath base_file_;

  void StartLogging() {
    ASSERT_TRUE(base::CreateTemporaryFile(&base_file_));
    EXPECT_TRUE(base::DeleteFile(base_file_, false));
    EXPECT_FALSE(base::PathExists(base_file_));
    EXPECT_TRUE(event_log_host_.StartWebRTCEventLog(base_file_));
    base::RunLoop().RunUntilIdle();
  }

  void StopLogging() {
    EXPECT_TRUE(event_log_host_.StopWebRTCEventLog());
    base::RunLoop().RunUntilIdle();
  }

  void ValidateStartIPCMessageAndCloseFile(const IPC::Message* msg,
                                           const int peer_connection_id) {
    ASSERT_TRUE(msg);
    std::tuple<int, IPC::PlatformFileForTransit> start_params;
    PeerConnectionTracker_StartEventLog::Read(msg, &start_params);
    EXPECT_EQ(peer_connection_id, std::get<0>(start_params));
    ASSERT_NE(IPC::InvalidPlatformFileForTransit(), std::get<1>(start_params));
    IPC::PlatformFileForTransitToFile(std::get<1>(start_params)).Close();
  }

  void ValidateStopIPCMessage(const IPC::Message* msg,
                              const int peer_connection_id) {
    ASSERT_TRUE(msg);
    std::tuple<int> stop_params;
    PeerConnectionTracker_StopEventLog::Read(msg, &stop_params);
    EXPECT_EQ(peer_connection_id, std::get<0>(stop_params));
  }
};

// This test calls StartWebRTCEventLog() and StopWebRTCEventLog() without having
// added any PeerConnections. It is expected that no IPC messages will be sent.
TEST_F(WebRtcEventlogHostTest, NoPeerConnectionTest) {
  mock_render_process_host_->sink().ClearMessages();

  // Start logging and check that no IPC messages were sent.
  StartLogging();
  EXPECT_EQ(size_t(0), mock_render_process_host_->sink().message_count());

  // Stop logging and check that no IPC messages were sent.
  StopLogging();
  EXPECT_EQ(size_t(0), mock_render_process_host_->sink().message_count());
}

// This test calls StartWebRTCEventLog() and StopWebRTCEventLog() after adding a
// single PeerConnection. It is expected that one IPC message will be sent for
// each of the Start and Stop calls, and that a logfile is created.
TEST_F(WebRtcEventlogHostTest, OnePeerConnectionTest) {
  const int kTestPeerConnectionId = 123;
  mock_render_process_host_->sink().ClearMessages();

  // Add a PeerConnection and start logging.
  event_log_host_.PeerConnectionAdded(kTestPeerConnectionId);
  StartLogging();

  // Check that the correct IPC message was sent.
  EXPECT_EQ(size_t(1), mock_render_process_host_->sink().message_count());
  const IPC::Message* start_msg =
      mock_render_process_host_->sink().GetMessageAt(0);
  ValidateStartIPCMessageAndCloseFile(start_msg, kTestPeerConnectionId);

  // Stop logging.
  mock_render_process_host_->sink().ClearMessages();
  StopLogging();

  // Check that the correct IPC message was sent.
  EXPECT_EQ(size_t(1), mock_render_process_host_->sink().message_count());
  const IPC::Message* stop_msg =
      mock_render_process_host_->sink().GetMessageAt(0);
  ValidateStopIPCMessage(stop_msg, kTestPeerConnectionId);

  // Clean up the logfile.
  base::FilePath expected_file = GetExpectedEventLogFileName(
      base_file_, render_id_, kTestPeerConnectionId);
  ASSERT_TRUE(base::PathExists(expected_file));
  EXPECT_TRUE(base::DeleteFile(expected_file, false));
}

// This test calls StartWebRTCEventLog() and StopWebRTCEventLog() after adding
// two PeerConnections. It is expected that two IPC messages will be sent for
// each of the Start and Stop calls, and that a file is created for both
// PeerConnections.
TEST_F(WebRtcEventlogHostTest, TwoPeerConnectionsTest) {
  const int kTestPeerConnectionId1 = 123;
  const int kTestPeerConnectionId2 = 321;
  mock_render_process_host_->sink().ClearMessages();

  // Add two PeerConnections and start logging.
  event_log_host_.PeerConnectionAdded(kTestPeerConnectionId1);
  event_log_host_.PeerConnectionAdded(kTestPeerConnectionId2);
  StartLogging();

  // Check that the correct IPC messages were sent.
  EXPECT_EQ(size_t(2), mock_render_process_host_->sink().message_count());
  const IPC::Message* start_msg1 =
      mock_render_process_host_->sink().GetMessageAt(0);
  ValidateStartIPCMessageAndCloseFile(start_msg1, kTestPeerConnectionId1);
  const IPC::Message* start_msg2 =
      mock_render_process_host_->sink().GetMessageAt(1);
  ValidateStartIPCMessageAndCloseFile(start_msg2, kTestPeerConnectionId2);

  // Stop logging.
  mock_render_process_host_->sink().ClearMessages();
  StopLogging();

  // Check that the correct IPC messages were sent.
  EXPECT_EQ(size_t(2), mock_render_process_host_->sink().message_count());
  const IPC::Message* stop_msg1 =
      mock_render_process_host_->sink().GetMessageAt(0);
  ValidateStopIPCMessage(stop_msg1, kTestPeerConnectionId1);
  const IPC::Message* stop_msg2 =
      mock_render_process_host_->sink().GetMessageAt(1);
  ValidateStopIPCMessage(stop_msg2, kTestPeerConnectionId2);

  // Clean up the logfiles.
  base::FilePath expected_file1 = GetExpectedEventLogFileName(
      base_file_, render_id_, kTestPeerConnectionId1);
  base::FilePath expected_file2 = GetExpectedEventLogFileName(
      base_file_, render_id_, kTestPeerConnectionId2);
  ASSERT_TRUE(base::PathExists(expected_file1));
  EXPECT_TRUE(base::DeleteFile(expected_file1, false));
  ASSERT_TRUE(base::PathExists(expected_file2));
  EXPECT_TRUE(base::DeleteFile(expected_file2, false));
}

// This test calls StartWebRTCEventLog() and StopWebRTCEventLog() after adding
// more PeerConnections than the maximum allowed. It is expected that only the
// maximum allowed number of IPC messages and log files will be opened, but we
// expect the number of stop IPC messages to be equal to the actual number of
// PeerConnections.
TEST_F(WebRtcEventlogHostTest, ExceedMaxPeerConnectionsTest) {
#if defined(OS_ANDROID)
  const int kMaxNumberLogFiles = 3;
#else
  const int kMaxNumberLogFiles = 5;
#endif
  const int kNumberOfPeerConnections = kMaxNumberLogFiles + 1;
  mock_render_process_host_->sink().ClearMessages();

  // Add the maximum number + 1 PeerConnections and start logging.
  for (int i = 0; i < kNumberOfPeerConnections; ++i)
    event_log_host_.PeerConnectionAdded(i);
  StartLogging();

  // Check that the correct IPC messages were sent.
  ASSERT_EQ(size_t(kMaxNumberLogFiles),
            mock_render_process_host_->sink().message_count());
  for (int i = 0; i < kMaxNumberLogFiles; ++i) {
    const IPC::Message* start_msg =
        mock_render_process_host_->sink().GetMessageAt(i);
    ValidateStartIPCMessageAndCloseFile(start_msg, i);
  }

  // Stop logging.
  mock_render_process_host_->sink().ClearMessages();
  StopLogging();

  // Check that the correct IPC messages were sent.
  ASSERT_EQ(size_t(kNumberOfPeerConnections),
            mock_render_process_host_->sink().message_count());
  for (int i = 0; i < kNumberOfPeerConnections; ++i) {
    const IPC::Message* stop_msg =
        mock_render_process_host_->sink().GetMessageAt(i);
    ValidateStopIPCMessage(stop_msg, i);
  }

  // Clean up the logfiles.
  for (int i = 0; i < kMaxNumberLogFiles; ++i) {
    base::FilePath expected_file =
        GetExpectedEventLogFileName(base_file_, render_id_, i);
    ASSERT_TRUE(base::PathExists(expected_file));
    EXPECT_TRUE(base::DeleteFile(expected_file, false));
  }

  // Check that not too many files were created.
  for (int i = kMaxNumberLogFiles; i < kNumberOfPeerConnections; ++i) {
    base::FilePath expected_file =
        GetExpectedEventLogFileName(base_file_, render_id_, i);
    EXPECT_FALSE(base::PathExists(expected_file));
  }
}

// This test calls StartWebRTCEventLog() and StopWebRTCEventLog() after first
// adding and then removing a single PeerConnection. It is expected that no IPC
// message will be sent.
TEST_F(WebRtcEventlogHostTest, AddRemovePeerConnectionTest) {
  const int kTestPeerConnectionId = 123;
  mock_render_process_host_->sink().ClearMessages();

  // Add and immediately remove a PeerConnection.
  event_log_host_.PeerConnectionAdded(kTestPeerConnectionId);
  event_log_host_.PeerConnectionRemoved(kTestPeerConnectionId);

  // Start logging and check that no IPC messages were sent.
  StartLogging();
  EXPECT_EQ(size_t(0), mock_render_process_host_->sink().message_count());

  // Stop logging and check that no IPC messages were sent.
  StopLogging();
  EXPECT_EQ(size_t(0), mock_render_process_host_->sink().message_count());

  // Check that no logfile was created.
  base::FilePath expected_file = GetExpectedEventLogFileName(
      base_file_, render_id_, kTestPeerConnectionId);
  ASSERT_FALSE(base::PathExists(expected_file));
}

}  // namespace content
