// 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 "include/base/cef_build.h"
#include "include/cef_config.h"

#if defined(OS_LINUX) && defined(CEF_X11)
#include <X11/Xlib.h>
// Definitions conflict with gtest.
#undef None
#undef Bool
#endif

#if defined(OS_POSIX)
#include <unistd.h>
#endif

#include "include/base/cef_callback.h"
#include "include/cef_app.h"
#include "include/cef_task.h"
#include "include/cef_thread.h"
#include "include/cef_waitable_event.h"
#include "include/wrapper/cef_closure_task.h"
#include "include/wrapper/cef_helpers.h"
#include "tests/ceftests/test_handler.h"
#include "tests/ceftests/test_server.h"
#include "tests/ceftests/test_suite.h"
#include "tests/shared/browser/client_app_browser.h"
#include "tests/shared/browser/main_message_loop_external_pump.h"
#include "tests/shared/browser/main_message_loop_std.h"
#include "tests/shared/common/client_app_other.h"
#include "tests/shared/renderer/client_app_renderer.h"

#if defined(OS_MAC)
#include "include/wrapper/cef_library_loader.h"
#endif

// When generating projects with CMake the CEF_USE_SANDBOX value will be defined
// automatically if using the required compiler version. Pass -DUSE_SANDBOX=OFF
// to the CMake command-line to disable use of the sandbox.
#if defined(OS_WIN) && defined(CEF_USE_SANDBOX)
#include "include/cef_sandbox_win.h"

// The cef_sandbox.lib static library may not link successfully with all VS
// versions.
#pragma comment(lib, "cef_sandbox.lib")
#endif

namespace {

void QuitMessageLoop() {
  CEF_REQUIRE_UI_THREAD();
  client::MainMessageLoop* message_loop = client::MainMessageLoop::Get();
  if (message_loop) {
    message_loop->Quit();
  } else {
    CefQuitMessageLoop();
  }
}

void sleep(int64_t ms) {
#if defined(OS_WIN)
  Sleep(ms);
#elif defined(OS_POSIX)
  usleep(static_cast<useconds_t>(ms * 1000));
#else
#error Unsupported platform
#endif
}

// Called on the test thread.
void RunTestsOnTestThread() {
  // Run the test suite.
  CefTestSuite::GetInstance()->Run();

  // Wait for all TestHandlers to be destroyed.
  while (TestHandler::HasTestHandler()) {
    sleep(100);
  }

  // Wait for the test server to stop, and then quit the CEF message loop.
  test_server::Stop(base::BindOnce(QuitMessageLoop));
}

// Called on the UI thread.
void ContinueOnUIThread(CefRefPtr<CefTaskRunner> test_task_runner) {
  // Run the test suite on the test thread.
  test_task_runner->PostTask(
      CefCreateClosureTask(base::BindOnce(&RunTestsOnTestThread)));
}

#if defined(OS_LINUX) && defined(CEF_X11)
int XErrorHandlerImpl(Display* display, XErrorEvent* event) {
  LOG(WARNING) << "X error received: "
               << "type " << event->type << ", "
               << "serial " << event->serial << ", "
               << "error_code " << static_cast<int>(event->error_code) << ", "
               << "request_code " << static_cast<int>(event->request_code)
               << ", "
               << "minor_code " << static_cast<int>(event->minor_code);
  return 0;
}

int XIOErrorHandlerImpl(Display* display) {
  return 0;
}
#endif  // defined(OS_LINUX) && defined(CEF_X11)

}  // namespace

int main(int argc, char* argv[]) {
#if !defined(OS_MAC)
  int exit_code;
#endif

#if defined(OS_WIN) && defined(ARCH_CPU_32_BITS)
  // Run the main thread on 32-bit Windows using a fiber with the preferred 4MiB
  // stack size. This function must be called at the top of the executable entry
  // point function (`main()` or `wWinMain()`). It is used in combination with
  // the initial stack size of 0.5MiB configured via the `/STACK:0x80000` linker
  // flag on executable targets. This saves significant memory on threads (like
  // those in the Windows thread pool, and others) whose stack size can only be
  // controlled via the linker flag.
  exit_code = CefRunMainWithPreferredStackSize(main, argc, argv);
  if (exit_code >= 0) {
    // The fiber has completed so return here.
    return exit_code;
  }
#endif

#if defined(OS_MAC)
  // Load the CEF framework library at runtime instead of linking directly
  // as required by the macOS sandbox implementation.
  CefScopedLibraryLoader library_loader;
  if (!library_loader.LoadInMain()) {
    return 1;
  }
#endif

  // Create the singleton test suite object.
  CefTestSuite test_suite(argc, argv);

#if defined(OS_WIN)
  CefMainArgs main_args(::GetModuleHandle(nullptr));
#else
  CefMainArgs main_args(argc, argv);
#endif

  void* windows_sandbox_info = nullptr;

#if defined(OS_WIN) && defined(CEF_USE_SANDBOX)
  // Manages the life span of the sandbox information object.
  CefScopedSandboxInfo scoped_sandbox;
  windows_sandbox_info = scoped_sandbox.sandbox_info();
#endif

  // Create a ClientApp of the correct type.
  CefRefPtr<CefApp> app;
  client::ClientApp::ProcessType process_type =
      client::ClientApp::GetProcessType(test_suite.command_line());
  if (process_type == client::ClientApp::BrowserProcess) {
    app = new client::ClientAppBrowser();
#if !defined(OS_MAC)
  } else if (process_type == client::ClientApp::RendererProcess ||
             process_type == client::ClientApp::ZygoteProcess) {
    app = new client::ClientAppRenderer();
  } else if (process_type == client::ClientApp::OtherProcess) {
    app = new client::ClientAppOther();
  }

  // Execute the secondary process, if any.
  exit_code = CefExecuteProcess(main_args, app, windows_sandbox_info);
  if (exit_code >= 0) {
    return exit_code;
  }
#else
  } else {
    // On OS X this executable is only used for the main process.
    NOTREACHED();
  }
#endif

  CefSettings settings;

#if !defined(CEF_USE_SANDBOX)
  settings.no_sandbox = true;
#endif

  client::ClientAppBrowser::PopulateSettings(test_suite.command_line(),
                                             settings);
  test_suite.GetSettings(settings);

#if defined(OS_MAC)
  // Platform-specific initialization.
  extern void PlatformInit();
  PlatformInit();
#endif

#if defined(OS_LINUX) && defined(CEF_X11)
  // Install xlib error handlers so that the application won't be terminated
  // on non-fatal errors.
  XSetErrorHandler(XErrorHandlerImpl);
  XSetIOErrorHandler(XIOErrorHandlerImpl);
#endif

  // Create the MessageLoop.
  std::unique_ptr<client::MainMessageLoop> message_loop;
  if (!settings.multi_threaded_message_loop) {
    if (settings.external_message_pump) {
      message_loop = client::MainMessageLoopExternalPump::Create();
    } else {
      message_loop.reset(new client::MainMessageLoopStd);
    }
  }

  // Initialize CEF.
  CefInitialize(main_args, settings, app, windows_sandbox_info);

  // Initialize the testing framework.
  test_suite.InitMainProcess();

  int retval;

  if (settings.multi_threaded_message_loop) {
    // Run the test suite on the main thread.
    retval = test_suite.Run();

    // Wait for the test server to stop.
    CefRefPtr<CefWaitableEvent> event =
        CefWaitableEvent::CreateWaitableEvent(true, false);
    test_server::Stop(base::BindOnce(&CefWaitableEvent::Signal, event));
    event->Wait();
  } else {
    // Create and start the test thread.
    CefRefPtr<CefThread> thread = CefThread::CreateThread("test_thread");
    if (!thread) {
      return 1;
    }

    // Start the tests from the UI thread so that any pending UI tasks get a
    // chance to execute first.
    CefPostTask(TID_UI,
                base::BindOnce(&ContinueOnUIThread, thread->GetTaskRunner()));

    // Run the CEF message loop.
    message_loop->Run();

    // The test suite has completed.
    retval = test_suite.retval();

    // Terminate the test thread.
    thread->Stop();
    thread = nullptr;
  }

  // Shut down CEF.
  CefShutdown();

  test_suite.DeleteTempDirectories();

  // Destroy the MessageLoop.
  message_loop.reset(nullptr);

#if defined(OS_MAC)
  // Platform-specific cleanup.
  extern void PlatformCleanup();
  PlatformCleanup();
#endif

  return retval;
}
