// Copyright (c) 2012 The Chromium Embedded Framework 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 "libcef/browser/context.h"
#include "libcef/browser/browser_host_impl.h"
#include "libcef/browser/browser_info.h"
#include "libcef/browser/browser_info_manager.h"
#include "libcef/browser/browser_main.h"
#include "libcef/browser/chrome_browser_process_stub.h"
#include "libcef/browser/thread_util.h"
#include "libcef/browser/trace_subscriber.h"
#include "libcef/common/cef_switches.h"
#include "libcef/common/main_delegate.h"
#include "libcef/common/widevine_loader.h"
#include "libcef/renderer/content_renderer_client.h"

#include "base/base_switches.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/debug/debugger.h"
#include "base/files/file_util.h"
#include "base/run_loop.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread_restrictions.h"
#include "components/network_session_configurator/common/network_switches.h"
#include "content/app/content_service_manager_main_delegate.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/common/content_switches.h"
#include "services/service_manager/embedder/main.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/ui_base_switches.h"

#if defined(OS_WIN)
#include "base/strings/utf_string_conversions.h"
#include "chrome/chrome_elf/chrome_elf_main.h"
#include "chrome/install_static/initialize_from_primary_module.h"
#include "components/crash/core/app/crashpad.h"
#include "content/public/app/sandbox_helper_win.h"
#include "sandbox/win/src/sandbox_types.h"
#endif

#if defined(OS_MACOSX) || defined(OS_WIN)
#include "components/crash/core/app/crash_switches.h"
#include "third_party/crashpad/crashpad/handler/handler_main.h"
#endif

namespace {

CefContext* g_context = nullptr;

#if DCHECK_IS_ON()
// When the process terminates check if CefShutdown() has been called.
class CefShutdownChecker {
 public:
  ~CefShutdownChecker() { DCHECK(!g_context) << "CefShutdown was not called"; }
} g_shutdown_checker;
#endif  // DCHECK_IS_ON()

#if defined(OS_WIN)
#if defined(ARCH_CPU_X86_64)
// VS2013 only checks the existence of FMA3 instructions, not the enabled-ness
// of them at the OS level (this is fixed in VS2015). We force off usage of
// FMA3 instructions in the CRT to avoid using that path and hitting illegal
// instructions when running on CPUs that support FMA3, but OSs that don't.
void DisableFMA3() {
  static bool disabled = false;
  if (disabled)
    return;
  disabled = true;
  _set_FMA3_enable(0);
}
#endif  // defined(ARCH_CPU_X86_64)

// Transfer state from chrome_elf.dll to the libcef.dll. Accessed when
// loading chrome://system.
void InitInstallDetails() {
  static bool initialized = false;
  if (initialized)
    return;
  initialized = true;
  install_static::InitializeFromPrimaryModule();
}

// Signal chrome_elf to initialize crash reporting, rather than doing it in
// DllMain. See https://crbug.com/656800 for details.
void InitCrashReporter() {
  static bool initialized = false;
  if (initialized)
    return;
  initialized = true;
  SignalInitializeCrashReporting();
}
#endif  // defined(OS_WIN)

#if defined(OS_MACOSX) || defined(OS_WIN)

// Based on components/crash/core/app/run_as_crashpad_handler_win.cc
// Remove the "--type=crashpad-handler" command-line flag that will otherwise
// confuse the crashpad handler.
// Chrome uses an embedded crashpad handler on Windows only and imports this
// function via the existing "run_as_crashpad_handler" target defined in
// components/crash/core/app/BUILD.gn. CEF uses an embedded handler on both
// Windows and macOS so we define the function here instead of using the
// existing target (because we can't use that target on macOS).
int RunAsCrashpadHandler(const base::CommandLine& command_line) {
  base::CommandLine::StringVector argv = command_line.argv();
  const base::CommandLine::StringType process_type =
      FILE_PATH_LITERAL("--type=");
  argv.erase(
      std::remove_if(argv.begin(), argv.end(),
                     [&process_type](const base::CommandLine::StringType& str) {
                       return base::StartsWith(str, process_type,
                                               base::CompareCase::SENSITIVE) ||
                              (!str.empty() && str[0] == L'/');
                     }),
      argv.end());

#if defined(OS_MACOSX)
  // HandlerMain on macOS uses the system version of getopt_long which expects
  // the first argument to be the program name.
  argv.insert(argv.begin(), command_line.GetProgram().value());
#endif

  std::unique_ptr<char*[]> argv_as_utf8(new char*[argv.size() + 1]);
  std::vector<std::string> storage;
  storage.reserve(argv.size());
  for (size_t i = 0; i < argv.size(); ++i) {
#if defined(OS_WIN)
    storage.push_back(base::UTF16ToUTF8(argv[i]));
#else
    storage.push_back(argv[i]);
#endif
    argv_as_utf8[i] = &storage[i][0];
  }
  argv_as_utf8[argv.size()] = nullptr;
  argv.clear();
  return crashpad::HandlerMain(static_cast<int>(storage.size()),
                               argv_as_utf8.get(), nullptr);
}

#endif  // defined(OS_MACOSX) || defined(OS_WIN)

bool GetColor(const cef_color_t cef_in, bool is_windowless, SkColor* sk_out) {
  // Windowed browser colors must be fully opaque.
  if (!is_windowless && CefColorGetA(cef_in) != SK_AlphaOPAQUE)
    return false;

  // Windowless browser colors may be fully transparent.
  if (is_windowless && CefColorGetA(cef_in) == SK_AlphaTRANSPARENT) {
    *sk_out = SK_ColorTRANSPARENT;
    return true;
  }

  // Ignore the alpha component.
  *sk_out = SkColorSetRGB(CefColorGetR(cef_in), CefColorGetG(cef_in),
                          CefColorGetB(cef_in));
  return true;
}

// Convert |path_str| to a normalized FilePath.
base::FilePath NormalizePath(const cef_string_t& path_str,
                             const char* name,
                             bool* has_error = nullptr) {
  if (has_error)
    *has_error = false;

  base::FilePath path = base::FilePath(CefString(&path_str));
  if (path.EndsWithSeparator()) {
    // Remove the trailing separator because it will interfere with future
    // equality checks.
    path = path.StripTrailingSeparators();
  }

  if (!path.empty() && !path.IsAbsolute()) {
    LOG(ERROR) << "The " << name << " directory (" << path.value()
               << ") is not an absolute path. Defaulting to empty.";
    if (has_error)
      *has_error = true;
    path = base::FilePath();
  }

  return path;
}

void SetPath(cef_string_t& path_str, const base::FilePath& path) {
#if defined(OS_WIN)
  CefString(&path_str).FromWString(path.value());
#else
  CefString(&path_str).FromString(path.value());
#endif
}

// Convert |path_str| to a normalized FilePath and update the |path_str| value.
base::FilePath NormalizePathAndSet(cef_string_t& path_str, const char* name) {
  const base::FilePath& path = NormalizePath(path_str, name);
  SetPath(path_str, path);
  return path;
}

// Verify that |cache_path| is valid and create it if necessary.
bool ValidateCachePath(const base::FilePath& cache_path,
                       const base::FilePath& root_cache_path) {
  if (cache_path.empty())
    return true;

  if (!root_cache_path.empty() && root_cache_path != cache_path &&
      !root_cache_path.IsParent(cache_path)) {
    LOG(ERROR) << "The cache_path directory (" << cache_path.value()
               << ") is not a child of the root_cache_path directory ("
               << root_cache_path.value() << ")";
    return false;
  }

  base::ThreadRestrictions::ScopedAllowIO allow_io;
  if (!base::DirectoryExists(cache_path) &&
      !base::CreateDirectory(cache_path)) {
    LOG(ERROR) << "The cache_path directory (" << cache_path.value()
               << ") could not be created.";
    return false;
  }

  return true;
}

// Like NormalizePathAndSet but with additional checks specific to the
// cache_path value.
base::FilePath NormalizeCachePathAndSet(cef_string_t& path_str,
                                        const base::FilePath& root_cache_path) {
  bool has_error = false;
  base::FilePath path = NormalizePath(path_str, "cache_path", &has_error);
  if (has_error || !ValidateCachePath(path, root_cache_path)) {
    LOG(ERROR) << "The cache_path is invalid. Defaulting to in-memory storage.";
    path = base::FilePath();
  }
  SetPath(path_str, path);
  return path;
}

}  // namespace

int CefExecuteProcess(const CefMainArgs& args,
                      CefRefPtr<CefApp> application,
                      void* windows_sandbox_info) {
#if defined(OS_WIN)
#if defined(ARCH_CPU_X86_64)
  DisableFMA3();
#endif
  InitInstallDetails();
  InitCrashReporter();
#endif

  base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
#if defined(OS_WIN)
  command_line.ParseFromString(::GetCommandLineW());
#else
  command_line.InitFromArgv(args.argc, args.argv);
#endif

  // Wait for the debugger as early in process initialization as possible.
  if (command_line.HasSwitch(switches::kWaitForDebugger))
    base::debug::WaitForDebugger(60, true);

  // If no process type is specified then it represents the browser process and
  // we do nothing.
  std::string process_type =
      command_line.GetSwitchValueASCII(switches::kProcessType);
  if (process_type.empty())
    return -1;

#if defined(OS_MACOSX) || defined(OS_WIN)
  if (process_type == crash_reporter::switches::kCrashpadHandler)
    return RunAsCrashpadHandler(command_line);
#endif

  CefMainDelegate main_delegate(application);

// Execute the secondary process.
#if defined(OS_WIN)
  sandbox::SandboxInterfaceInfo sandbox_info = {0};
  if (windows_sandbox_info == nullptr) {
    content::InitializeSandboxInfo(&sandbox_info);
    windows_sandbox_info = &sandbox_info;
  }

  content::ContentMainParams params(&main_delegate);
  params.instance = args.instance;
  params.sandbox_info =
      static_cast<sandbox::SandboxInterfaceInfo*>(windows_sandbox_info);

  return content::ContentMain(params);
#else
  content::ContentMainParams params(&main_delegate);
  params.argc = args.argc;
  params.argv = const_cast<const char**>(args.argv);

  return content::ContentMain(params);
#endif
}

bool CefInitialize(const CefMainArgs& args,
                   const CefSettings& settings,
                   CefRefPtr<CefApp> application,
                   void* windows_sandbox_info) {
#if defined(OS_WIN)
#if defined(ARCH_CPU_X86_64)
  DisableFMA3();
#endif
  InitInstallDetails();
  InitCrashReporter();
#endif

  // Return true if the global context already exists.
  if (g_context)
    return true;

  if (settings.size != sizeof(cef_settings_t)) {
    NOTREACHED() << "invalid CefSettings structure size";
    return false;
  }

  g_browser_process = new ChromeBrowserProcessStub();

  // Create the new global context object.
  g_context = new CefContext();

  // Initialize the global context.
  return g_context->Initialize(args, settings, application,
                               windows_sandbox_info);
}

void CefShutdown() {
  // Verify that the context is in a valid state.
  if (!CONTEXT_STATE_VALID()) {
    NOTREACHED() << "context not valid";
    return;
  }

  // Must always be called on the same thread as Initialize.
  if (!g_context->OnInitThread()) {
    NOTREACHED() << "called on invalid thread";
    return;
  }

  // Shut down the global context. This will block until shutdown is complete.
  g_context->Shutdown();

  // Delete the global context object.
  delete g_context;
  g_context = nullptr;
}

void CefDoMessageLoopWork() {
  // Verify that the context is in a valid state.
  if (!CONTEXT_STATE_VALID()) {
    NOTREACHED() << "context not valid";
    return;
  }

  // Must always be called on the same thread as Initialize.
  if (!g_context->OnInitThread()) {
    NOTREACHED() << "called on invalid thread";
    return;
  }

  base::RunLoop run_loop;
  run_loop.RunUntilIdle();
}

void CefRunMessageLoop() {
  // Verify that the context is in a valid state.
  if (!CONTEXT_STATE_VALID()) {
    NOTREACHED() << "context not valid";
    return;
  }

  // Must always be called on the same thread as Initialize.
  if (!g_context->OnInitThread()) {
    NOTREACHED() << "called on invalid thread";
    return;
  }

  base::RunLoop run_loop;
  run_loop.Run();
}

void CefQuitMessageLoop() {
  // Verify that the context is in a valid state.
  if (!CONTEXT_STATE_VALID()) {
    NOTREACHED() << "context not valid";
    return;
  }

  // Must always be called on the same thread as Initialize.
  if (!g_context->OnInitThread()) {
    NOTREACHED() << "called on invalid thread";
    return;
  }

  // Quit the CefBrowserMessageLoop.
  base::RunLoop::QuitCurrentWhenIdleDeprecated();
}

void CefSetOSModalLoop(bool osModalLoop) {
#if defined(OS_WIN)
  // Verify that the context is in a valid state.
  if (!CONTEXT_STATE_VALID()) {
    NOTREACHED() << "context not valid";
    return;
  }

  if (CEF_CURRENTLY_ON_UIT())
    base::MessageLoopCurrent::Get()->set_os_modal_loop(osModalLoop);
  else
    CEF_POST_TASK(CEF_UIT, base::Bind(CefSetOSModalLoop, osModalLoop));
#endif  // defined(OS_WIN)
}

// CefContext

CefContext::CefContext()
    : initialized_(false), shutting_down_(false), init_thread_id_(0) {}

CefContext::~CefContext() {}

// static
CefContext* CefContext::Get() {
  return g_context;
}

bool CefContext::Initialize(const CefMainArgs& args,
                            const CefSettings& settings,
                            CefRefPtr<CefApp> application,
                            void* windows_sandbox_info) {
  init_thread_id_ = base::PlatformThread::CurrentId();
  settings_ = settings;

#if !(defined(OS_WIN) || defined(OS_LINUX))
  if (settings.multi_threaded_message_loop) {
    NOTIMPLEMENTED() << "multi_threaded_message_loop is not supported.";
    return false;
  }
#endif

#if defined(OS_WIN)
  // Signal Chrome Elf that Chrome has begun to start.
  SignalChromeElf();
#endif

  const base::FilePath& root_cache_path =
      NormalizePathAndSet(settings_.root_cache_path, "root_cache_path");
  const base::FilePath& cache_path =
      NormalizeCachePathAndSet(settings_.cache_path, root_cache_path);
  if (root_cache_path.empty() && !cache_path.empty()) {
    CefString(&settings_.root_cache_path) = cache_path.value();
  }

  // All other paths that need to be normalized.
  NormalizePathAndSet(settings_.browser_subprocess_path,
                      "browser_subprocess_path");
  NormalizePathAndSet(settings_.framework_dir_path, "framework_dir_path");
  NormalizePathAndSet(settings_.main_bundle_path, "main_bundle_path");
  NormalizePathAndSet(settings_.user_data_path, "user_data_path");
  NormalizePathAndSet(settings_.resources_dir_path, "resources_dir_path");
  NormalizePathAndSet(settings_.locales_dir_path, "locales_dir_path");

  main_delegate_.reset(new CefMainDelegate(application));
  browser_info_manager_.reset(new CefBrowserInfoManager);

  int exit_code;

  // Initialize the content runner.
  content::ContentMainParams params(main_delegate_.get());
#if defined(OS_WIN)
  sandbox::SandboxInterfaceInfo sandbox_info = {0};
  if (windows_sandbox_info == nullptr) {
    windows_sandbox_info = &sandbox_info;
    settings_.no_sandbox = true;
  }

  params.instance = args.instance;
  params.sandbox_info =
      static_cast<sandbox::SandboxInterfaceInfo*>(windows_sandbox_info);
#else
  params.argc = args.argc;
  params.argv = const_cast<const char**>(args.argv);
#endif

  sm_main_delegate_.reset(
      new content::ContentServiceManagerMainDelegate(params));
  sm_main_params_.reset(
      new service_manager::MainParams(sm_main_delegate_.get()));

#if defined(OS_POSIX) && !defined(OS_ANDROID)
  sm_main_params_->argc = params.argc;
  sm_main_params_->argv = params.argv;
#endif

  exit_code = service_manager::MainInitialize(*sm_main_params_);
  DCHECK_LT(exit_code, 0);
  if (exit_code >= 0)
    return false;

  static_cast<ChromeBrowserProcessStub*>(g_browser_process)->Initialize();

  if (settings.multi_threaded_message_loop) {
    base::WaitableEvent uithread_startup_event(
        base::WaitableEvent::ResetPolicy::AUTOMATIC,
        base::WaitableEvent::InitialState::NOT_SIGNALED);

    if (!main_delegate_->CreateUIThread(base::BindOnce(
            [](CefContext* context, base::WaitableEvent* event) {
              service_manager::MainRun(*context->sm_main_params_);
              event->Signal();
            },
            base::Unretained(this),
            base::Unretained(&uithread_startup_event)))) {
      return false;
    }

    initialized_ = true;

    // We need to wait until service_manager::MainRun has finished.
    uithread_startup_event.Wait();
  } else {
    initialized_ = true;
    service_manager::MainRun(*sm_main_params_);
  }

  if (CEF_CURRENTLY_ON_UIT()) {
    OnContextInitialized();
  } else {
    // Continue initialization on the UI thread.
    CEF_POST_TASK(CEF_UIT, base::Bind(&CefContext::OnContextInitialized,
                                      base::Unretained(this)));
  }

  return true;
}

void CefContext::Shutdown() {
  // Must always be called on the same thread as Initialize.
  DCHECK(OnInitThread());

  shutting_down_ = true;

  if (settings_.multi_threaded_message_loop) {
    // Events that will be used to signal when shutdown is complete. Start in
    // non-signaled mode so that the event will block.
    base::WaitableEvent uithread_shutdown_event(
        base::WaitableEvent::ResetPolicy::AUTOMATIC,
        base::WaitableEvent::InitialState::NOT_SIGNALED);

    // Finish shutdown on the UI thread.
    CEF_POST_TASK(CEF_UIT,
                  base::Bind(&CefContext::FinishShutdownOnUIThread,
                             base::Unretained(this), &uithread_shutdown_event));

    /// Block until UI thread shutdown is complete.
    uithread_shutdown_event.Wait();

    FinalizeShutdown();
  } else {
    // Finish shutdown on the current thread, which should be the UI thread.
    FinishShutdownOnUIThread(nullptr);

    FinalizeShutdown();
  }
}

bool CefContext::OnInitThread() {
  return (base::PlatformThread::CurrentId() == init_thread_id_);
}

SkColor CefContext::GetBackgroundColor(
    const CefBrowserSettings* browser_settings,
    cef_state_t windowless_state) const {
  bool is_windowless = windowless_state == STATE_ENABLED
                           ? true
                           : (windowless_state == STATE_DISABLED
                                  ? false
                                  : !!settings_.windowless_rendering_enabled);

  // Default to opaque white if no acceptable color values are found.
  SkColor sk_color = SK_ColorWHITE;

  if (!browser_settings ||
      !GetColor(browser_settings->background_color, is_windowless, &sk_color)) {
    GetColor(settings_.background_color, is_windowless, &sk_color);
  }
  return sk_color;
}

CefTraceSubscriber* CefContext::GetTraceSubscriber() {
  CEF_REQUIRE_UIT();
  if (shutting_down_)
    return nullptr;
  if (!trace_subscriber_.get())
    trace_subscriber_.reset(new CefTraceSubscriber());
  return trace_subscriber_.get();
}

void CefContext::PopulateGlobalRequestContextSettings(
    CefRequestContextSettings* settings) {
  CefRefPtr<CefCommandLine> command_line =
      CefCommandLine::GetGlobalCommandLine();

  // This value was already normalized in Initialize.
  CefString(&settings->cache_path) = CefString(&settings_.cache_path);

  settings->persist_session_cookies =
      settings_.persist_session_cookies ||
      command_line->HasSwitch(switches::kPersistSessionCookies);
  settings->persist_user_preferences =
      settings_.persist_user_preferences ||
      command_line->HasSwitch(switches::kPersistUserPreferences);
  settings->ignore_certificate_errors =
      settings_.ignore_certificate_errors ||
      command_line->HasSwitch(switches::kIgnoreCertificateErrors);
  CefString(&settings->accept_language_list) =
      CefString(&settings_.accept_language_list);
}

void CefContext::NormalizeRequestContextSettings(
    CefRequestContextSettings* settings) {
  // The |root_cache_path| value was already normalized in Initialize.
  const base::FilePath& root_cache_path = CefString(&settings_.root_cache_path);
  NormalizeCachePathAndSet(settings->cache_path, root_cache_path);

  if (settings->accept_language_list.length == 0) {
    // Use the global language list setting.
    CefString(&settings->accept_language_list) =
        CefString(&settings_.accept_language_list);
  }
}

void CefContext::AddObserver(Observer* observer) {
  CEF_REQUIRE_UIT();
  observers_.AddObserver(observer);
}

void CefContext::RemoveObserver(Observer* observer) {
  CEF_REQUIRE_UIT();
  observers_.RemoveObserver(observer);
}

bool CefContext::HasObserver(Observer* observer) const {
  CEF_REQUIRE_UIT();
  return observers_.HasObserver(observer);
}

void CefContext::OnContextInitialized() {
  CEF_REQUIRE_UIT();

  static_cast<ChromeBrowserProcessStub*>(g_browser_process)
      ->OnContextInitialized();

#if BUILDFLAG(ENABLE_WIDEVINE) && BUILDFLAG(ENABLE_LIBRARY_CDMS)
  CefWidevineLoader::GetInstance()->OnContextInitialized();
#endif

  // Notify the handler.
  CefRefPtr<CefApp> app = CefContentClient::Get()->application();
  if (app.get()) {
    CefRefPtr<CefBrowserProcessHandler> handler =
        app->GetBrowserProcessHandler();
    if (handler.get())
      handler->OnContextInitialized();
  }
}

void CefContext::FinishShutdownOnUIThread(
    base::WaitableEvent* uithread_shutdown_event) {
  CEF_REQUIRE_UIT();

  browser_info_manager_->DestroyAllBrowsers();

  for (auto& observer : observers_)
    observer.OnContextDestroyed();

  if (trace_subscriber_.get())
    trace_subscriber_.reset(nullptr);

  static_cast<ChromeBrowserProcessStub*>(g_browser_process)->Shutdown();

  ui::ResourceBundle::GetSharedInstance().CleanupOnUIThread();

  sm_main_delegate_->ShutdownOnUIThread();

  if (uithread_shutdown_event)
    uithread_shutdown_event->Signal();
}

void CefContext::FinalizeShutdown() {
  if (content::RenderProcessHost::run_renderer_in_process()) {
    // Blocks until RenderProcess cleanup is complete.
    CefContentRendererClient::Get()->RunSingleProcessCleanup();
  }

  // Shut down the browser runner or UI thread.
  main_delegate_->ShutdownBrowser();

  // Shut down the content runner.
  service_manager::MainShutdown(*sm_main_params_);

  browser_info_manager_.reset(nullptr);
  sm_main_params_.reset(nullptr);
  sm_main_delegate_.reset(nullptr);
  main_delegate_.reset(nullptr);

  delete g_browser_process;
  g_browser_process = nullptr;
}
