// Copyright 2015 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 "ash/window_manager_service.h"

#include <memory>
#include <utility>

#include "ash/mojo_interface_factory.h"
#include "ash/network_connect_delegate_mus.h"
#include "ash/public/cpp/config.h"
#include "ash/shell.h"
#include "ash/shell_delegate.h"
#include "ash/system/power/power_status.h"
#include "ash/window_manager.h"
#include "base/bind.h"
#include "base/threading/thread_task_runner_handle.h"
#include "chromeos/audio/cras_audio_handler.h"
#include "chromeos/cryptohome/system_salt_getter.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/network/network_connect.h"
#include "chromeos/network/network_handler.h"
#include "chromeos/system/fake_statistics_provider.h"
#include "device/bluetooth/bluetooth_adapter_factory.h"
#include "device/bluetooth/dbus/bluez_dbus_manager.h"
#include "services/service_manager/public/cpp/connector.h"
#include "services/service_manager/public/cpp/service_context.h"
#include "services/ui/common/accelerator_util.h"
#include "ui/aura/env.h"
#include "ui/aura/mus/window_tree_client.h"
#include "ui/events/event.h"
#include "ui/message_center/message_center.h"
#include "ui/views/mus/aura_init.h"

namespace ash {

WindowManagerService::WindowManagerService(
    bool show_primary_host_on_connect,
    Config ash_config,
    std::unique_ptr<ash::ShellDelegate> shell_delegate)
    : show_primary_host_on_connect_(show_primary_host_on_connect),
      shell_delegate_(std::move(shell_delegate)),
      ash_config_(ash_config) {}

WindowManagerService::~WindowManagerService() {
  // Verify that we created a WindowManager before attempting to tear everything
  // down. In some fast running tests OnStart may never have been called.
  if (!window_manager_.get())
    return;

  // Destroy the WindowManager while still valid. This way we ensure
  // OnWillDestroyRootWindowController() is called (if it hasn't been already).
  window_manager_.reset();

  statistics_provider_.reset();
  ShutdownComponents();
}

service_manager::Connector* WindowManagerService::GetConnector() {
  return context() ? context()->connector() : nullptr;
}

void WindowManagerService::InitWindowManager(
    std::unique_ptr<aura::WindowTreeClient> window_tree_client,
    bool init_network_handler) {
  // Tests may have already set the WindowTreeClient.
  if (!aura::Env::GetInstance()->HasWindowTreeClient())
    aura::Env::GetInstance()->SetWindowTreeClient(window_tree_client.get());
  InitializeComponents(init_network_handler);

  // TODO(jamescook): Refactor StatisticsProvider so we can get just the data
  // we need in ash. Right now StatisticsProviderImpl launches the crossystem
  // binary to get system data, which we don't want to do twice on startup.
  statistics_provider_.reset(
      new chromeos::system::ScopedFakeStatisticsProvider());
  statistics_provider_->SetMachineStatistic("initial_locale", "en-US");
  statistics_provider_->SetMachineStatistic("keyboard_layout", "");

  window_manager_->Init(std::move(window_tree_client),
                        std::move(shell_delegate_));
}

void WindowManagerService::InitializeComponents(bool init_network_handler) {
  message_center::MessageCenter::Initialize();

  // Must occur after mojo::ApplicationRunner has initialized AtExitManager, but
  // before WindowManager::Init(). Tests might initialize their own instance.
  if (!chromeos::DBusThreadManager::IsInitialized()) {
    chromeos::DBusThreadManager::Initialize(
        chromeos::DBusThreadManager::PROCESS_ASH);
    dbus_thread_manager_initialized_ = true;
  }

  // See ChromeBrowserMainPartsChromeos for ordering details.
  bluez::BluezDBusManager::Initialize(
      chromeos::DBusThreadManager::Get()->GetSystemBus(),
      chromeos::DBusThreadManager::Get()->IsUsingFakes());
  if (init_network_handler && !chromeos::NetworkHandler::IsInitialized()) {
    chromeos::NetworkHandler::Initialize();
    network_handler_initialized_ = true;
  }
  network_connect_delegate_.reset(new NetworkConnectDelegateMus());
  chromeos::NetworkConnect::Initialize(network_connect_delegate_.get());
  // TODO(jamescook): Initialize real audio handler.
  chromeos::CrasAudioHandler::InitializeForTesting();
  chromeos::SystemSaltGetter::Initialize();
}

void WindowManagerService::ShutdownComponents() {
  // NOTE: PowerStatus is shutdown by Shell.
  chromeos::SystemSaltGetter::Shutdown();
  chromeos::CrasAudioHandler::Shutdown();
  chromeos::NetworkConnect::Shutdown();
  network_connect_delegate_.reset();
  // We may not have started the NetworkHandler.
  if (network_handler_initialized_)
    chromeos::NetworkHandler::Shutdown();
  device::BluetoothAdapterFactory::Shutdown();
  bluez::BluezDBusManager::Shutdown();
  if (dbus_thread_manager_initialized_)
    chromeos::DBusThreadManager::Shutdown();
  message_center::MessageCenter::Shutdown();
}

void WindowManagerService::OnStart() {
  mojo_interface_factory::RegisterInterfaces(
      &registry_, base::ThreadTaskRunnerHandle::Get());

  const bool register_path_provider = running_standalone_;
  aura_init_ = views::AuraInit::Create(
      context()->connector(), context()->identity(),
      "ash_service_resources.pak", "ash_service_resources_200.pak", nullptr,
      views::AuraInit::Mode::AURA_MUS_WINDOW_MANAGER, register_path_provider);
  if (!aura_init_) {
    context()->QuitNow();
    return;
  }
  window_manager_ = std::make_unique<WindowManager>(
      context()->connector(), ash_config_, show_primary_host_on_connect_);

  std::unique_ptr<aura::WindowTreeClient> window_tree_client =
      std::make_unique<aura::WindowTreeClient>(
          context()->connector(), window_manager_.get(), window_manager_.get());
  const bool automatically_create_display_roots = false;
  window_tree_client->ConnectAsWindowManager(
      automatically_create_display_roots);

  const bool init_network_handler = true;
  InitWindowManager(std::move(window_tree_client), init_network_handler);
}

void WindowManagerService::OnBindInterface(
    const service_manager::BindSourceInfo& source_info,
    const std::string& interface_name,
    mojo::ScopedMessagePipeHandle interface_pipe) {
  registry_.BindInterface(interface_name, std::move(interface_pipe));
}

}  // namespace ash
