// Copyright 2013 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 "shell/android/main.h"

#include <stdio.h>

#include "base/android/fifo_utils.h"
#include "base/android/jni_android.h"
#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
#include "base/at_exit.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/synchronization/waitable_event.h"
#include "base/task_runner_util.h"
#include "base/threading/simple_thread.h"
#include "gpu/config/gpu_util.h"
#include "jni/ShellService_jni.h"
#include "mojo/common/binding_set.h"
#include "mojo/message_pump/message_pump_mojo.h"
#include "mojo/services/network/interfaces/network_service.mojom.h"
#include "mojo/services/window_manager/interfaces/window_manager.mojom.h"
#include "shell/android/android_handler_loader.h"
#include "shell/android/java_application_loader.h"
#include "shell/android/native_viewport_application_loader.h"
#include "shell/android/ui_application_loader_android.h"
#include "shell/android/url_response_disk_cache_delegate_impl.h"
#include "shell/application_manager/application_loader.h"
#include "shell/application_manager/shell_impl.h"
#include "shell/background_application_loader.h"
#include "shell/command_line_util.h"
#include "shell/context.h"
#include "shell/crash/breakpad.h"
#include "shell/crash/crash_upload.h"
#include "shell/init.h"
#include "shell/switches.h"
#include "shell/tracer.h"
#include "ui/gl/gl_surface_egl.h"

using base::LazyInstance;

namespace shell {

namespace {

// Command line argument for the communication fifo.
const char kFifoPath[] = "fifo-path";

// Delay before trying to upload a crash report. This must not slow down
// startup.
const int kDelayBeforeCrashUploadInSeconds = 60;

class MojoShellRunner : public base::DelegateSimpleThread::Delegate {
 public:
  MojoShellRunner(const base::FilePath& mojo_shell_child_path)
      : mojo_shell_child_path_(mojo_shell_child_path) {}
  ~MojoShellRunner() override {}

 private:
  void Run() override;

  const base::FilePath mojo_shell_child_path_;

  DISALLOW_COPY_AND_ASSIGN(MojoShellRunner);
};

// Structure to hold internal data used to setup the Mojo shell.
struct InternalShellData {
  // java_message_loop is the main thread/UI thread message loop.
  scoped_ptr<base::MessageLoop> java_message_loop;

  // tracer, accessible on the main thread
  scoped_ptr<Tracer> tracer;

  // Shell context, accessible on the shell thread
  scoped_ptr<Context> context;

  // Shell runner (thread delegate), to be uesd by the shell thread.
  scoped_ptr<MojoShellRunner> shell_runner;

  // Thread to run the shell on.
  scoped_ptr<base::DelegateSimpleThread> shell_thread;

  // TaskRunner used to execute tasks on the shell thread.
  scoped_refptr<base::SingleThreadTaskRunner> shell_task_runner;

  // Event signalling when the shell task runner has been initialized.
  scoped_ptr<base::WaitableEvent> shell_runner_ready;

  // Delegate for URLResponseDiskCache. Allows to access bundled application on
  // cold start.
  scoped_ptr<URLResponseDiskCacheDelegateImpl> url_response_disk_cache_delegate;

  // Shell implementation to expose to java.
  scoped_ptr<ShellImpl> shell_impl;

  // Binding set to the shell implementation.
  mojo::BindingSet<mojo::Shell> shell_bindings;
};

LazyInstance<InternalShellData> g_internal_data = LAZY_INSTANCE_INITIALIZER;

void ConfigureAndroidServices(Context* context) {
  context->application_manager()->SetLoaderForURL(
      make_scoped_ptr(new UIApplicationLoader(
          make_scoped_ptr(new NativeViewportApplicationLoader()),
          g_internal_data.Get().java_message_loop.get())),
      GURL("mojo:native_viewport_service"));

  // Android handler is bundled with the Mojo shell, because it uses the
  // MojoShell application as the JNI bridge to bootstrap execution of other
  // Android Mojo apps that need JNI.
  context->application_manager()->SetLoaderForURL(
      make_scoped_ptr(new BackgroundApplicationLoader(
          make_scoped_ptr(new AndroidHandlerLoader()), "android_handler",
          base::MessageLoop::TYPE_DEFAULT)),
      GURL("mojo:android_handler"));

  // Register java applications.
  base::android::ScopedJavaGlobalRef<jobject> java_application_registry(
      JavaApplicationLoader::CreateJavaApplicationRegistry());
  for (const auto& url : JavaApplicationLoader::GetApplicationURLs(
           java_application_registry.obj())) {
    context->application_manager()->SetLoaderForURL(
        make_scoped_ptr(
            new JavaApplicationLoader(java_application_registry, url)),
        GURL(url));
  }

  // By default, the authenticated_network_service is handled by the
  // authentication service.
  context->url_resolver()->AddURLMapping(
      GURL("mojo:authenticated_network_service"), GURL("mojo:authentication"));
}

void QuitShellThread() {
  g_internal_data.Get().shell_thread->Join();
  g_internal_data.Get().shell_thread.reset();
  Java_ShellService_finishActivities(base::android::AttachCurrentThread());
  exit(0);
}

void MojoShellRunner::Run() {
  base::MessageLoop loop(mojo::common::MessagePumpMojo::Create());
  g_internal_data.Get().shell_task_runner = loop.task_runner();
  // Signal that the shell is ready to receive requests.
  g_internal_data.Get().shell_runner_ready->Signal();

  Context* context = g_internal_data.Get().context.get();
  ConfigureAndroidServices(context);
  CHECK(context->InitWithPaths(
      mojo_shell_child_path_,
      g_internal_data.Get().url_response_disk_cache_delegate.get()));

  RunCommandLineApps(context);

  loop.Run();

  g_internal_data.Get().java_message_loop.get()->PostTask(
      FROM_HERE, base::Bind(&QuitShellThread));
}

// Initialize stdout redirection if the command line switch is present.
void InitializeRedirection() {
  if (!base::CommandLine::ForCurrentProcess()->HasSwitch(kFifoPath))
    return;

  base::FilePath fifo_path =
      base::CommandLine::ForCurrentProcess()->GetSwitchValuePath(kFifoPath);
  base::FilePath directory = fifo_path.DirName();
  CHECK(base::CreateDirectoryAndGetError(directory, nullptr))
      << "Unable to create directory: " << directory.value();
  unlink(fifo_path.value().c_str());
  CHECK(base::android::CreateFIFO(fifo_path, 0666)) << "Unable to create fifo: "
                                                    << fifo_path.value();
  CHECK(base::android::RedirectStream(stdout, fifo_path, "w"))
      << "Failed to redirect stdout to file: " << fifo_path.value();
  CHECK(dup2(STDOUT_FILENO, STDERR_FILENO) != -1)
      << "Unable to redirect stderr to stdout.";
  // Set stdout to be line buffered to match what one expects when running
  // attached to a terminal.
  if (setvbuf(stdout, NULL, _IONBF, 0) != 0)
    LOG(ERROR) << "Failed to set stdout to be line buffered.";
}

void BindShellImpl(mojo::ScopedMessagePipeHandle shell_handle) {
  Context* context = g_internal_data.Get().context.get();
  if (!g_internal_data.Get().shell_impl.get()) {
    // The application proxy is null, as the shell is not connectable from other
    // applications.
    mojo::ApplicationPtr application;
    // The identity of the shell is the empty URL.
    GURL identity;
    g_internal_data.Get().shell_impl.reset(
        new ShellImpl(application.Pass(), context->application_manager(),
                      Identity(identity), base::Closure()));
  }
  mojo::InterfaceRequest<mojo::Shell> shell;
  shell.Bind(shell_handle.Pass());
  g_internal_data.Get().shell_bindings.AddBinding(
      g_internal_data.Get().shell_impl.get(), shell.Pass());
}

void StartApplicationByURL(std::string url) {
  DCHECK(g_internal_data.Get().shell_task_runner->RunsTasksOnCurrentThread());

  g_internal_data.Get().context->Run(GURL(url));
}

void UploadCrashes(const base::FilePath& dumps_path) {
  DCHECK(g_internal_data.Get().shell_task_runner->RunsTasksOnCurrentThread());
  Context* context = g_internal_data.Get().context.get();
  mojo::NetworkServicePtr network_service;
  context->application_manager()->ConnectToService(GURL("mojo:network_service"),
                                                   &network_service);
  breakpad::UploadCrashes(dumps_path, context->task_runners()->blocking_pool(),
                          network_service.Pass());
}

}  // namespace

static void Start(JNIEnv* env,
                  jclass clazz,
                  jobject application_context,
                  jobject j_asset_manager,
                  jstring mojo_shell_child_path,
                  jobjectArray jparameters,
                  jstring j_local_apps_directory,
                  jstring j_tmp_dir,
                  jstring j_home_dir) {
  // Initially, the shell runner is not ready.
  g_internal_data.Get().shell_runner_ready.reset(
      new base::WaitableEvent(true, false));

  std::string tmp_dir = base::android::ConvertJavaStringToUTF8(env, j_tmp_dir);
  // Setting the TMPDIR and HOME environment variables so that applications can
  // use it.
  // TODO(qsr) We will need our subprocesses to inherit this.
  int return_value = setenv("TMPDIR", tmp_dir.c_str(), 1);
  DCHECK_EQ(return_value, 0);
  return_value = setenv(
      "HOME", base::android::ConvertJavaStringToUTF8(env, j_home_dir).c_str(),
      1);
  DCHECK_EQ(return_value, 0);

  base::android::ScopedJavaLocalRef<jobject> scoped_application_context(
      env, application_context);
  base::android::InitApplicationContext(env, scoped_application_context);

  std::vector<std::string> parameters;
  parameters.push_back("mojo_shell");
  base::android::AppendJavaStringArrayToStringVector(env, jparameters,
                                                     &parameters);
  base::CommandLine::Init(0, nullptr);
  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  command_line->InitFromArgv(parameters);

  base::FilePath dumps_path = base::FilePath(tmp_dir).Append("breakpad_dumps");
  breakpad::InitCrashReporter(dumps_path);

  Tracer* tracer = new Tracer;
  g_internal_data.Get().tracer.reset(tracer);
  bool trace_startup = command_line->HasSwitch(switches::kTraceStartup);
  if (trace_startup) {
    std::string output_name =
        command_line->GetSwitchValueASCII(switches::kTraceStartupOutputName);
    std::string output_path =
        tmp_dir + "/" +
        (output_name.empty() ? "mojo_shell.trace" : output_name);
    tracer->Start(
        command_line->GetSwitchValueASCII(switches::kTraceStartup),
        command_line->GetSwitchValueASCII(switches::kTraceStartupDuration),
        output_path);
  }

  g_internal_data.Get().shell_runner.reset(new MojoShellRunner(base::FilePath(
      base::android::ConvertJavaStringToUTF8(env, mojo_shell_child_path))));

  InitializeLogging();

  InitializeRedirection();

  // We want ~MessageLoop to happen prior to ~Context. Initializing
  // LazyInstances is akin to stack-allocating objects; their destructors
  // will be invoked first-in-last-out.
  Context* shell_context = new Context(tracer);
  shell_context->SetShellFileRoot(base::FilePath(
      base::android::ConvertJavaStringToUTF8(env, j_local_apps_directory)));
  g_internal_data.Get().context.reset(shell_context);

  g_internal_data.Get().url_response_disk_cache_delegate.reset(
      new URLResponseDiskCacheDelegateImpl(shell_context, j_asset_manager));

  g_internal_data.Get().java_message_loop.reset(new base::MessageLoopForUI);
  base::MessageLoopForUI::current()->Start();
  tracer->DidCreateMessageLoop();

  g_internal_data.Get().shell_thread.reset(new base::DelegateSimpleThread(
      g_internal_data.Get().shell_runner.get(), "ShellThread"));
  g_internal_data.Get().shell_thread->Start();

  // TODO(abarth): At which point should we switch to cross-platform
  // initialization?

  gfx::GLSurface::InitializeOneOff();

  g_internal_data.Get().shell_runner_ready->Wait();

  // Upload crashes after one minute.
  g_internal_data.Get().shell_task_runner->PostDelayedTask(
      FROM_HERE, base::Bind(&UploadCrashes, dumps_path),
      base::TimeDelta::FromSeconds(kDelayBeforeCrashUploadInSeconds));

  gpu::ApplyGpuDriverBugWorkarounds(command_line);
}

static void AddApplicationURL(JNIEnv* env, jclass clazz, jstring jurl) {
  base::CommandLine::ForCurrentProcess()->AppendArg(
      base::android::ConvertJavaStringToUTF8(env, jurl));
}

static void StartApplicationURL(JNIEnv* env, jclass clazz, jstring jurl) {
  std::string url = base::android::ConvertJavaStringToUTF8(env, jurl);
  g_internal_data.Get().shell_task_runner->PostTask(
      FROM_HERE, base::Bind(&StartApplicationByURL, url));
}

static void BindShell(JNIEnv* env, jclass clazz, jint shell_handle) {
  g_internal_data.Get().shell_task_runner->PostTask(
      FROM_HERE,
      base::Bind(&BindShellImpl, base::Passed(mojo::ScopedMessagePipeHandle(
                                     mojo::MessagePipeHandle(shell_handle)))));
}

bool RegisterShellService(JNIEnv* env) {
  return RegisterNativesImpl(env);
}

}  // namespace shell
