// Copyright (c) 2012 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 "remoting/host/daemon_process.h"

#include <stdint.h>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/location.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted.h"
#include "base/message_loop/message_loop.h"
#include "base/process/process.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "ipc/ipc_channel_handle.h"
#include "ipc/ipc_message.h"
#include "ipc/ipc_message_macros.h"
#include "remoting/base/auto_thread_task_runner.h"
#include "remoting/host/chromoting_messages.h"
#include "remoting/host/desktop_session.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gmock_mutant.h"
#include "testing/gtest/include/gtest/gtest.h"

using testing::_;
using testing::AnyNumber;
using testing::InSequence;

namespace remoting {

namespace {

enum Messages {
  kMessageCrash = ChromotingDaemonMsg_Crash::ID,
  kMessageConfiguration = ChromotingDaemonNetworkMsg_Configuration::ID,
  kMessageConnectTerminal = ChromotingNetworkHostMsg_ConnectTerminal::ID,
  kMessageDisconnectTerminal = ChromotingNetworkHostMsg_DisconnectTerminal::ID,
  kMessageTerminalDisconnected =
      ChromotingDaemonNetworkMsg_TerminalDisconnected::ID,
  kMessageReportProcessStats = ChromotingAnyToNetworkMsg_ReportProcessStats::ID,
};

// Provides a public constructor allowing the test to create instances of
// DesktopSession directly.
class FakeDesktopSession : public DesktopSession {
 public:
  FakeDesktopSession(DaemonProcess* daemon_process, int id);
  ~FakeDesktopSession() override;

  void SetScreenResolution(const ScreenResolution& resolution) override {}

 private:
  DISALLOW_COPY_AND_ASSIGN(FakeDesktopSession);
};

class MockDaemonProcess : public DaemonProcess {
 public:
  MockDaemonProcess(
      scoped_refptr<AutoThreadTaskRunner> caller_task_runner,
      scoped_refptr<AutoThreadTaskRunner> io_task_runner,
      const base::Closure& stopped_callback);
  ~MockDaemonProcess() override;

  std::unique_ptr<DesktopSession> DoCreateDesktopSession(
      int terminal_id,
      const ScreenResolution& resolution,
      bool virtual_terminal) override;

  bool OnMessageReceived(const IPC::Message& message) override;
  void SendToNetwork(IPC::Message* message) override;

  MOCK_METHOD1(Received, void(const IPC::Message&));
  MOCK_METHOD1(Sent, void(const IPC::Message&));

  MOCK_METHOD3(OnDesktopSessionAgentAttached,
               bool(int, int, const IPC::ChannelHandle&));

  MOCK_METHOD1(DoCreateDesktopSessionPtr, DesktopSession*(int));
  MOCK_METHOD1(DoCrashNetworkProcess, void(const tracked_objects::Location&));
  MOCK_METHOD0(LaunchNetworkProcess, void());

 private:
  DISALLOW_COPY_AND_ASSIGN(MockDaemonProcess);
};

FakeDesktopSession::FakeDesktopSession(DaemonProcess* daemon_process, int id)
    : DesktopSession(daemon_process, id) {
}

FakeDesktopSession::~FakeDesktopSession() {
}

MockDaemonProcess::MockDaemonProcess(
    scoped_refptr<AutoThreadTaskRunner> caller_task_runner,
    scoped_refptr<AutoThreadTaskRunner> io_task_runner,
    const base::Closure& stopped_callback)
    : DaemonProcess(caller_task_runner, io_task_runner, stopped_callback) {
}

MockDaemonProcess::~MockDaemonProcess() {
}

std::unique_ptr<DesktopSession> MockDaemonProcess::DoCreateDesktopSession(
    int terminal_id,
    const ScreenResolution& resolution,
    bool virtual_terminal) {
  return base::WrapUnique(DoCreateDesktopSessionPtr(terminal_id));
}

bool MockDaemonProcess::OnMessageReceived(const IPC::Message& message) {
  // Notify the mock method.
  Received(message);

  // Call the actual handler.
  return DaemonProcess::OnMessageReceived(message);
}

void MockDaemonProcess::SendToNetwork(IPC::Message* message) {
  // Notify the mock method.
  Sent(*message);
  delete message;
}

}  // namespace

class DaemonProcessTest : public testing::Test {
 public:
  DaemonProcessTest();
  ~DaemonProcessTest() override;

  void SetUp() override;
  void TearDown() override;

  // DaemonProcess mocks
  DesktopSession* DoCreateDesktopSession(int terminal_id);
  void DoCrashNetworkProcess(const tracked_objects::Location& location);
  void LaunchNetworkProcess();

  // Deletes |daemon_process_|.
  void DeleteDaemonProcess();

  // Quits |message_loop_|.
  void QuitMessageLoop();

  void StartDaemonProcess();

  const DaemonProcess::DesktopSessionList& desktop_sessions() const {
    return daemon_process_->desktop_sessions();
  }

 protected:
  base::MessageLoopForIO message_loop_;

  std::unique_ptr<MockDaemonProcess> daemon_process_;
  int terminal_id_;
};

DaemonProcessTest::DaemonProcessTest() : terminal_id_(0) {
}

DaemonProcessTest::~DaemonProcessTest() {
}

void DaemonProcessTest::SetUp() {
  scoped_refptr<AutoThreadTaskRunner> task_runner = new AutoThreadTaskRunner(
      message_loop_.task_runner(),
      base::Bind(&DaemonProcessTest::QuitMessageLoop,
                 base::Unretained(this)));
  daemon_process_.reset(
      new MockDaemonProcess(task_runner, task_runner,
                            base::Bind(&DaemonProcessTest::DeleteDaemonProcess,
                                       base::Unretained(this))));

  // Set up daemon process mocks.
  EXPECT_CALL(*daemon_process_, DoCreateDesktopSessionPtr(_))
      .Times(AnyNumber())
      .WillRepeatedly(Invoke(this, &DaemonProcessTest::DoCreateDesktopSession));
  EXPECT_CALL(*daemon_process_, DoCrashNetworkProcess(_))
      .Times(AnyNumber())
      .WillRepeatedly(Invoke(this, &DaemonProcessTest::DoCrashNetworkProcess));
  EXPECT_CALL(*daemon_process_, LaunchNetworkProcess())
      .Times(AnyNumber())
      .WillRepeatedly(Invoke(this, &DaemonProcessTest::LaunchNetworkProcess));
}

void DaemonProcessTest::TearDown() {
  daemon_process_->Stop();
  base::RunLoop().Run();
}

DesktopSession* DaemonProcessTest::DoCreateDesktopSession(int terminal_id) {
  return new FakeDesktopSession(daemon_process_.get(), terminal_id);
}

void DaemonProcessTest::DoCrashNetworkProcess(
    const tracked_objects::Location& location) {
  daemon_process_->SendToNetwork(
      new ChromotingDaemonMsg_Crash(location.function_name(),
                                    location.file_name(),
                                    location.line_number()));
}

void DaemonProcessTest::LaunchNetworkProcess() {
  terminal_id_ = 0;
  daemon_process_->OnChannelConnected(0);
}

void DaemonProcessTest::DeleteDaemonProcess() {
  daemon_process_.reset();
}

void DaemonProcessTest::QuitMessageLoop() {
  message_loop_.task_runner()->PostTask(
      FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
}

void DaemonProcessTest::StartDaemonProcess() {
  // DaemonProcess::Initialize() sets up the config watcher that this test does
  // not support. Launch the process directly.
  daemon_process_->LaunchNetworkProcess();
}

MATCHER_P(Message, type, "") {
  return arg.type() == static_cast<uint32_t>(type);
}

TEST_F(DaemonProcessTest, OpenClose) {
  InSequence s;
  EXPECT_CALL(*daemon_process_, Sent(Message(kMessageConfiguration)));
  EXPECT_CALL(*daemon_process_, Received(Message(kMessageConnectTerminal)));
  EXPECT_CALL(*daemon_process_, Received(Message(kMessageDisconnectTerminal)));
  EXPECT_CALL(*daemon_process_, Sent(Message(kMessageTerminalDisconnected)));

  StartDaemonProcess();

  int id = terminal_id_++;
  ScreenResolution resolution;

  EXPECT_TRUE(daemon_process_->OnMessageReceived(
      ChromotingNetworkHostMsg_ConnectTerminal(id, resolution, false)));
  EXPECT_EQ(1u, desktop_sessions().size());
  EXPECT_EQ(id, desktop_sessions().front()->id());

  EXPECT_TRUE(daemon_process_->OnMessageReceived(
      ChromotingNetworkHostMsg_DisconnectTerminal(id)));
  EXPECT_TRUE(desktop_sessions().empty());
}

TEST_F(DaemonProcessTest, CallCloseDesktopSession) {
  InSequence s;
  EXPECT_CALL(*daemon_process_, Sent(Message(kMessageConfiguration)));
  EXPECT_CALL(*daemon_process_, Received(Message(kMessageConnectTerminal)));
  EXPECT_CALL(*daemon_process_, Sent(Message(kMessageTerminalDisconnected)));

  StartDaemonProcess();

  int id = terminal_id_++;
  ScreenResolution resolution;

  EXPECT_TRUE(daemon_process_->OnMessageReceived(
      ChromotingNetworkHostMsg_ConnectTerminal(id, resolution, false)));
  EXPECT_EQ(1u, desktop_sessions().size());
  EXPECT_EQ(id, desktop_sessions().front()->id());

  daemon_process_->CloseDesktopSession(id);
  EXPECT_TRUE(desktop_sessions().empty());
}

// Sends two CloseDesktopSession messages and expects the second one to be
// ignored.
TEST_F(DaemonProcessTest, DoubleDisconnectTerminal) {
  InSequence s;
  EXPECT_CALL(*daemon_process_, Sent(Message(kMessageConfiguration)));
  EXPECT_CALL(*daemon_process_, Received(Message(kMessageConnectTerminal)));
  EXPECT_CALL(*daemon_process_, Received(Message(kMessageDisconnectTerminal)));
  EXPECT_CALL(*daemon_process_, Sent(Message(kMessageTerminalDisconnected)));
  EXPECT_CALL(*daemon_process_, Received(Message(kMessageDisconnectTerminal)));

  StartDaemonProcess();

  int id = terminal_id_++;
  ScreenResolution resolution;

  EXPECT_TRUE(daemon_process_->OnMessageReceived(
      ChromotingNetworkHostMsg_ConnectTerminal(id, resolution, false)));
  EXPECT_EQ(1u, desktop_sessions().size());
  EXPECT_EQ(id, desktop_sessions().front()->id());

  EXPECT_TRUE(daemon_process_->OnMessageReceived(
      ChromotingNetworkHostMsg_DisconnectTerminal(id)));
  EXPECT_TRUE(desktop_sessions().empty());

  EXPECT_TRUE(daemon_process_->OnMessageReceived(
      ChromotingNetworkHostMsg_DisconnectTerminal(id)));
  EXPECT_TRUE(desktop_sessions().empty());
}

// Tries to close an invalid terminal ID and expects the network process to be
// restarted.
TEST_F(DaemonProcessTest, InvalidDisconnectTerminal) {
  InSequence s;
  EXPECT_CALL(*daemon_process_, Sent(Message(kMessageConfiguration)));
  EXPECT_CALL(*daemon_process_, Received(Message(kMessageDisconnectTerminal)));
  EXPECT_CALL(*daemon_process_, Sent(Message(kMessageCrash)))
      .WillOnce(InvokeWithoutArgs(this,
                                  &DaemonProcessTest::LaunchNetworkProcess));
  EXPECT_CALL(*daemon_process_, Sent(Message(kMessageConfiguration)));

  StartDaemonProcess();

  int id = terminal_id_++;

  EXPECT_TRUE(daemon_process_->OnMessageReceived(
      ChromotingNetworkHostMsg_DisconnectTerminal(id)));
  EXPECT_TRUE(desktop_sessions().empty());
  EXPECT_EQ(0, terminal_id_);
}

// Tries to open an invalid terminal ID and expects the network process to be
// restarted.
TEST_F(DaemonProcessTest, InvalidConnectTerminal) {
  InSequence s;
  EXPECT_CALL(*daemon_process_, Sent(Message(kMessageConfiguration)));
  EXPECT_CALL(*daemon_process_, Received(Message(kMessageConnectTerminal)));
  EXPECT_CALL(*daemon_process_, Received(Message(kMessageConnectTerminal)));
  EXPECT_CALL(*daemon_process_, Sent(Message(kMessageCrash)))
      .WillOnce(InvokeWithoutArgs(this,
                                  &DaemonProcessTest::LaunchNetworkProcess));
  EXPECT_CALL(*daemon_process_, Sent(Message(kMessageConfiguration)));

  StartDaemonProcess();

  int id = terminal_id_++;
  ScreenResolution resolution;

  EXPECT_TRUE(daemon_process_->OnMessageReceived(
      ChromotingNetworkHostMsg_ConnectTerminal(id, resolution, false)));
  EXPECT_EQ(1u, desktop_sessions().size());
  EXPECT_EQ(id, desktop_sessions().front()->id());

  EXPECT_TRUE(daemon_process_->OnMessageReceived(
      ChromotingNetworkHostMsg_ConnectTerminal(id, resolution, false)));
  EXPECT_TRUE(desktop_sessions().empty());
  EXPECT_EQ(0, terminal_id_);
}

TEST_F(DaemonProcessTest, StartProcessStatsReport) {
  EXPECT_CALL(*daemon_process_, Sent(Message(kMessageReportProcessStats)));
  daemon_process_->OnMessageReceived(
      ChromotingNetworkToAnyMsg_StartProcessStatsReport(
          base::TimeDelta::FromMilliseconds(1)));
  base::RunLoop run_loop;
  ON_CALL(*daemon_process_, Sent(Message(kMessageReportProcessStats)))
      .WillByDefault(testing::Invoke(
          [&run_loop](const IPC::Message& message) {
            run_loop.Quit();
          }));
  run_loop.Run();
}

TEST_F(DaemonProcessTest, StartProcessStatsReportWithDifferentDelta) {
  EXPECT_CALL(*daemon_process_, Sent(Message(kMessageReportProcessStats)))
      .Times(AnyNumber());
  int received = 0;
  daemon_process_->OnMessageReceived(
      ChromotingNetworkToAnyMsg_StartProcessStatsReport(
          base::TimeDelta::FromHours(1)));
  daemon_process_->OnMessageReceived(
      ChromotingNetworkToAnyMsg_StartProcessStatsReport(
          base::TimeDelta::FromMilliseconds(1)));
  base::RunLoop run_loop;
  ON_CALL(*daemon_process_, Sent(Message(kMessageReportProcessStats)))
      .WillByDefault(testing::Invoke(
          [&run_loop, &received](const IPC::Message& message) {
            received++;
            if (received == 5) {
              run_loop.Quit();
            }
          }));
  run_loop.Run();
}

TEST_F(DaemonProcessTest, StopProcessStatsReportWhenTheWorkerProcessDied) {
  daemon_process_->OnMessageReceived(
      ChromotingNetworkToAnyMsg_StartProcessStatsReport(
          base::TimeDelta::FromMilliseconds(1)));
  base::RunLoop run_loop;
  ON_CALL(*daemon_process_, Sent(Message(kMessageReportProcessStats)))
      .WillByDefault(testing::Invoke(
          [](const IPC::Message& message) {
            ASSERT_TRUE(false);
          }));
  static_cast<WorkerProcessIpcDelegate*>(daemon_process_.get())
      ->OnWorkerProcessStopped();
  message_loop_.task_runner()->PostDelayedTask(
      FROM_HERE, run_loop.QuitClosure(), base::TimeDelta::FromMilliseconds(10));
  run_loop.Run();
}

}  // namespace remoting
