// Copyright 2017 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 "chrome/browser/chrome_service.h"

#include "base/bind.h"
#include "base/no_destructor.h"
#include "base/single_thread_task_runner.h"
#include "base/task/post_task.h"
#include "chrome/browser/chrome_browser_main_extra_parts.h"
#include "chrome/common/constants.mojom.h"
#include "components/spellcheck/spellcheck_buildflags.h"
#include "components/startup_metric_utils/browser/startup_metric_host_impl.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/common/content_client.h"
#include "content/public/common/service_manager_connection.h"
#include "services/service_manager/public/cpp/binder_registry.h"
#include "services/service_manager/public/cpp/connector.h"
#include "services/service_manager/public/cpp/service.h"
#include "services/service_manager/public/cpp/service_binding.h"

#if defined(OS_CHROMEOS)
#include "services/ws/public/cpp/input_devices/input_device_controller.h"
#endif
#if BUILDFLAG(ENABLE_SPELLCHECK)
#include "chrome/browser/spellchecker/spell_check_host_chrome_impl.h"
#if BUILDFLAG(HAS_SPELLCHECK_PANEL)
#include "chrome/browser/spellchecker/spell_check_panel_host_impl.h"
#endif
#endif

class ChromeService::IOThreadContext : public service_manager::Service {
 public:
  IOThreadContext() {
    scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner =
        base::CreateSingleThreadTaskRunnerWithTraits(
            {content::BrowserThread::UI});

#if defined(OS_CHROMEOS)
    input_device_controller_.AddInterface(&registry_, ui_task_runner);
#endif
    registry_.AddInterface(base::BindRepeating(
        &startup_metric_utils::StartupMetricHostImpl::Create));
#if BUILDFLAG(ENABLE_SPELLCHECK)
    registry_with_source_info_.AddInterface(
        base::BindRepeating(&SpellCheckHostChromeImpl::Create), ui_task_runner);
#if BUILDFLAG(HAS_SPELLCHECK_PANEL)
    registry_.AddInterface(
        base::BindRepeating(&SpellCheckPanelHostImpl::Create), ui_task_runner);
#endif
#endif
  }
  ~IOThreadContext() override = default;

  void BindServiceRequest(service_manager::mojom::ServiceRequest request) {
    service_binding_.Bind(std::move(request));
  }

  void BindConnector(
      service_manager::mojom::ConnectorRequest connector_request) {
    DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

    // NOTE: It's not safe to modify |connector_request_| here since it's read
    // on the IO thread. Post a task instead. As long as this task is posted
    // before any code attempts to connect to the chrome service, there's no
    // race.
    base::CreateSingleThreadTaskRunnerWithTraits({content::BrowserThread::IO})
        ->PostTask(FROM_HERE,
                   base::BindOnce(&IOThreadContext::BindConnectorOnIOThread,
                                  base::Unretained(this),
                                  std::move(connector_request)));
  }

 private:
  void BindConnectorOnIOThread(
      service_manager::mojom::ConnectorRequest connector_request) {
    DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
    connector_request_ = std::move(connector_request);
  }

  // service_manager::Service:
  void OnStart() override {
    DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
    DCHECK(connector_request_.is_pending());
    service_binding_.GetConnector()->BindConnectorRequest(
        std::move(connector_request_));
  }

  void OnBindInterface(const service_manager::BindSourceInfo& remote_info,
                       const std::string& name,
                       mojo::ScopedMessagePipeHandle handle) override {
    DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
    content::OverrideOnBindInterface(remote_info, name, &handle);
    if (!handle.is_valid())
      return;

    if (!registry_.TryBindInterface(name, &handle))
      registry_with_source_info_.TryBindInterface(name, &handle, remote_info);
  }

  service_manager::mojom::ConnectorRequest connector_request_;

  service_manager::ServiceBinding service_binding_{this};
  service_manager::BinderRegistry registry_;
  service_manager::BinderRegistryWithArgs<
      const service_manager::BindSourceInfo&>
      registry_with_source_info_;

#if defined(OS_CHROMEOS)
  ws::InputDeviceController input_device_controller_;
#endif

  DISALLOW_COPY_AND_ASSIGN(IOThreadContext);
};

class ChromeService::ExtraParts : public ChromeBrowserMainExtraParts {
 public:
  ExtraParts() = default;
  ~ExtraParts() override = default;

 private:
  void ServiceManagerConnectionStarted(
      content::ServiceManagerConnection* connection) override {
    // Initializing the connector asynchronously configures the Connector on the
    // IO thread. This needs to be done before WarmService() is called or
    // ChromeService::BindConnector() can race with ChromeService::OnStart().
    ChromeService::GetInstance()->InitConnector();

    // TODO(https://crbug.com/904148): This should not use |WarmService()|.
    connection->GetConnector()->WarmService(
        service_manager::ServiceFilter::ByName(chrome::mojom::kServiceName));
  }

  DISALLOW_COPY_AND_ASSIGN(ExtraParts);
};

// static
ChromeService* ChromeService::GetInstance() {
  static base::NoDestructor<ChromeService> service;
  return service.get();
}

ChromeBrowserMainExtraParts* ChromeService::CreateExtraParts() {
  return new ExtraParts;
}

content::ServiceManagerConnection::ServiceRequestHandler
ChromeService::CreateChromeServiceRequestHandler() {
  return base::BindRepeating(&ChromeService::BindChromeServiceRequest,
                             base::Unretained(this));
}

ChromeService::ChromeService()
    : io_thread_context_(std::make_unique<IOThreadContext>()) {}

ChromeService::~ChromeService() = default;

void ChromeService::InitConnector() {
  service_manager::mojom::ConnectorRequest request;
  connector_ = service_manager::Connector::Create(&request);
  io_thread_context_->BindConnector(std::move(request));
}

void ChromeService::BindChromeServiceRequest(
    service_manager::mojom::ServiceRequest request) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
  io_thread_context_->BindServiceRequest(std::move(request));
}
