// 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.
//
// This file implements the Windows service controlling Me2Me host processes
// running within user sessions.

#include <memory>
#include <utility>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/command_line.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "build/build_config.h"
#include "mojo/edk/embedder/embedder.h"
#include "mojo/edk/embedder/incoming_broker_client_invitation.h"
#include "mojo/edk/embedder/named_platform_channel_pair.h"
#include "mojo/edk/embedder/platform_channel_pair.h"
#include "mojo/edk/embedder/scoped_ipc_support.h"
#include "remoting/base/auto_thread.h"
#include "remoting/base/auto_thread_task_runner.h"
#include "remoting/host/desktop_process.h"
#include "remoting/host/host_exit_codes.h"
#include "remoting/host/host_main.h"
#include "remoting/host/me2me_desktop_environment.h"
#include "remoting/host/switches.h"
#include "remoting/host/win/session_desktop_environment.h"

namespace remoting {

int DesktopProcessMain() {
  const base::CommandLine* command_line =
      base::CommandLine::ForCurrentProcess();
  base::MessageLoopForUI message_loop;
  base::RunLoop run_loop;
  scoped_refptr<AutoThreadTaskRunner> ui_task_runner =
      new AutoThreadTaskRunner(message_loop.task_runner(),
                               run_loop.QuitClosure());

  // Launch the video capture thread.
  scoped_refptr<AutoThreadTaskRunner> video_capture_task_runner =
      AutoThread::Create("Video capture thread", ui_task_runner);

  // Launch the input thread.
  scoped_refptr<AutoThreadTaskRunner> input_task_runner =
      AutoThread::CreateWithType(
          "Input thread", ui_task_runner, base::MessageLoop::TYPE_IO);

  // Launch the I/O thread.
  scoped_refptr<AutoThreadTaskRunner> io_task_runner =
      AutoThread::CreateWithType("I/O thread", ui_task_runner,
                                 base::MessageLoop::TYPE_IO);

  mojo::edk::ScopedIPCSupport ipc_support(
      io_task_runner->task_runner(),
      mojo::edk::ScopedIPCSupport::ShutdownPolicy::FAST);
  mojo::edk::ScopedPlatformHandle parent_pipe =
      mojo::edk::PlatformChannelPair::PassClientHandleFromParentProcess(
          *command_line);
  if (!parent_pipe.is_valid()) {
    parent_pipe =
        mojo::edk::NamedPlatformChannelPair::PassClientHandleFromParentProcess(
            *command_line);
  }
  if (!parent_pipe.is_valid()) {
    return kInvalidCommandLineExitCode;
  }

  auto invitation = mojo::edk::IncomingBrokerClientInvitation::Accept(
      mojo::edk::ConnectionParams(mojo::edk::TransportProtocol::kLegacy,
                                  std::move(parent_pipe)));
  mojo::ScopedMessagePipeHandle message_pipe = invitation->ExtractMessagePipe(
      command_line->GetSwitchValueASCII(kMojoPipeToken));
  DesktopProcess desktop_process(ui_task_runner, input_task_runner,
                                 io_task_runner, std::move(message_pipe));

  // Create a platform-dependent environment factory.
  std::unique_ptr<DesktopEnvironmentFactory> desktop_environment_factory;
#if defined(OS_WIN)
  // base::Unretained() is safe here: |desktop_process| outlives run_loop.Run().
  auto inject_sas_closure = base::Bind(&DesktopProcess::InjectSas,
                                       base::Unretained(&desktop_process));
  auto lock_workstation_closure = base::Bind(
      &DesktopProcess::LockWorkstation, base::Unretained(&desktop_process));

  desktop_environment_factory.reset(new SessionDesktopEnvironmentFactory(
      ui_task_runner, video_capture_task_runner, input_task_runner,
      ui_task_runner, inject_sas_closure, lock_workstation_closure));
#else  // !defined(OS_WIN)
  desktop_environment_factory.reset(new Me2MeDesktopEnvironmentFactory(
      ui_task_runner, video_capture_task_runner, input_task_runner,
      ui_task_runner));
#endif  // !defined(OS_WIN)

  if (!desktop_process.Start(std::move(desktop_environment_factory)))
    return kInitializationFailed;

  // Run the UI message loop.
  ui_task_runner = nullptr;
  run_loop.Run();

  return kSuccessExitCode;
}

}  // namespace remoting

#if !defined(OS_WIN)
int main(int argc, char** argv) {
  return remoting::HostMain(argc, argv);
}
#endif  // !defined(OS_WIN)
