// Copyright 2014 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 "base/at_exit.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/string_split.h"
#include "mojo/edk/embedder/embedder.h"
#include "mojo/edk/embedder/process_delegate.h"
#include "mojo/edk/embedder/simple_platform_support.h"
#include "shell/dynamic_service_runner.h"
#include "shell/external_application_registrar_connection.h"
#include "shell/in_process_dynamic_service_runner.h"
#include "shell/init.h"
#include "url/gurl.h"

namespace mojo {

const char kAppArgs[] = "app-args";
const char kAppPath[] = "app-path";
const char kAppURL[] = "app-url";
const char kShellPath[] = "shell-path";

class Launcher : public embedder::ProcessDelegate {
 public:
  explicit Launcher(const base::CommandLine& command_line)
      : app_path_(command_line.GetSwitchValuePath(kAppPath)),
        app_url_(command_line.GetSwitchValueASCII(kAppURL)),
        loop_(base::MessageLoop::TYPE_IO),
        connection_(new shell::ExternalApplicationRegistrarConnection(
            base::FilePath(command_line.GetSwitchValuePath(kShellPath)))) {
    // TODO(vtl): I guess this should be SLAVE, not NONE?
    embedder::InitIPCSupport(embedder::ProcessType::NONE, loop_.task_runner(),
                             this, loop_.task_runner(),
                             embedder::ScopedPlatformHandle());

    base::SplitStringAlongWhitespace(command_line.GetSwitchValueASCII(kAppArgs),
                                     &app_args_);
  }

  ~Launcher() {
    // TODO(vtl): We need to destroy this before calling
    // ShutdownIPCSupportOnIOThread(). This is all quite sketchy, and we really
    // should convert all of this to running the application on the main thread,
    // with a separate I/O thread (and managing the lifetime of everything more
    // carefully).
    connection_.reset();
    DCHECK(!application_request_.is_pending());

    embedder::ShutdownIPCSupportOnIOThread();
  }

  bool Connect() { return connection_->Connect(); }

  bool Register() {
    base::RunLoop run_loop;
    connection_->Register(
        app_url_, app_args_,
        base::Bind(&Launcher::OnRegistered, base::Unretained(this),
                   base::Unretained(&run_loop)));
    run_loop.Run();
    return application_request_.is_pending();
  }

  void Run() {
    DCHECK(application_request_.is_pending());
    shell::InProcessDynamicServiceRunner service_runner(nullptr);
    base::RunLoop run_loop;
    service_runner.Start(app_path_,
                         shell::DynamicServiceRunner::DontDeleteAppPath,
                         application_request_.Pass(), run_loop.QuitClosure());
    run_loop.Run();
  }

 private:
  void OnRegistered(base::RunLoop* run_loop,
                    InterfaceRequest<Application> application_request) {
    application_request_ = application_request.Pass();
    run_loop->Quit();
  }

  // embedder::ProcessDelegate implementation:
  void OnShutdownComplete() override {
    NOTREACHED();  // Not called since we use ShutdownIPCSupportOnIOThread().
  }

  const base::FilePath app_path_;
  const GURL app_url_;
  std::vector<std::string> app_args_;
  base::MessageLoop loop_;
  scoped_ptr<shell::ExternalApplicationRegistrarConnection> connection_;
  InterfaceRequest<Application> application_request_;

  DISALLOW_COPY_AND_ASSIGN(Launcher);
};

}  // namespace mojo

int main(int argc, char** argv) {
  base::AtExitManager at_exit;
  mojo::embedder::Init(
      make_scoped_ptr(new mojo::embedder::SimplePlatformSupport()));

  base::CommandLine::Init(argc, argv);
  const base::CommandLine* command_line =
      base::CommandLine::ForCurrentProcess();
  mojo::shell::InitializeLogging();

  mojo::Launcher launcher(*command_line);
  if (!launcher.Connect()) {
    LOG(ERROR) << "Failed to connect on socket "
               << command_line->GetSwitchValueASCII(mojo::kShellPath);
    return 1;
  }

  if (!launcher.Register()) {
    LOG(ERROR) << "Error registering "
               << command_line->GetSwitchValueASCII(mojo::kAppURL);
    return 1;
  }

  launcher.Run();
  return 0;
}
