// Copyright 2015 The Chromium OS 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 "germ/launcher.h"

#include <sys/types.h>

#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/rand_util.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_split.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
#include <chromeos/minijail/minijail.h>

namespace {
const char* kSandboxedServiceTemplate = "germ_template";
const size_t kStdoutBufSize = 1024;
}  // namespace

namespace germ {

// Starts with the top half of user ids.
class UidService final {
 public:
  UidService() { min_uid_ = 1 << ((sizeof(uid_t) * 8) >> 1); }
  ~UidService() {}

  uid_t GetUid() {
    return static_cast<uid_t>(base::RandInt(min_uid_, 2 * min_uid_));
  }

 private:
  uid_t min_uid_;
};

Launcher::Launcher() {
  uid_service_.reset(new UidService());
}

Launcher::~Launcher() {}

bool Launcher::RunInteractiveCommand(const std::string& name,
                                     const std::vector<std::string>& argv,
                                     int* status) {
  std::vector<char*> cmdline;
  for (const auto& t : argv) {
    cmdline.push_back(const_cast<char*>(t.c_str()));
  }
  // Minijail will use the underlying char* array as 'argv',
  // so null-terminate it.
  cmdline.push_back(nullptr);

  uid_t uid = uid_service_->GetUid();
  Environment env(uid, uid);

  return RunWithMinijail(env, cmdline, status);
}

bool Launcher::RunInteractiveSpec(const soma::ReadOnlyContainerSpec& spec,
                                  int* status) {
  std::vector<char*> cmdline;
  // TODO(jorgelo): support running more than one executable.
  for (const auto& t : spec.executables()[0]->command_line) {
    cmdline.push_back(const_cast<char*>(t.c_str()));
  }
  // Minijail will use the underlying char* array as 'argv',
  // so null-terminate it.
  cmdline.push_back(nullptr);

  Environment env(spec.executables()[0]->uid, spec.executables()[0]->gid);
  return RunWithMinijail(env, cmdline, status);
}

bool Launcher::RunWithMinijail(const Environment& env,
                               const std::vector<char*>& cmdline,
                               int* status) {
  chromeos::Minijail* minijail = chromeos::Minijail::GetInstance();
  return minijail->RunSyncAndDestroy(env.GetForInteractive(), cmdline,
                                     status);
}

bool Launcher::RunDaemonized(const soma::ReadOnlyContainerSpec& spec,
                             pid_t* pid) {
  // initctl start germ_template NAME=yes ENVIRONMENT= COMMANDLINE=/usr/bin/yes
  std::vector<std::string> argv;
  // TODO(jorgelo): support running more than one executable.
  for (const auto& cmdline_token : spec.executables()[0]->command_line) {
    argv.push_back(cmdline_token);
  }

  Environment env(spec.executables()[0]->uid, spec.executables()[0]->gid);

  std::unique_ptr<chromeos::Process> initctl = GetProcessInstance();
  initctl->AddArg("/sbin/initctl");
  initctl->AddArg("start");
  initctl->AddArg(kSandboxedServiceTemplate);
  initctl->AddArg(base::StringPrintf("NAME=%s", spec.name().c_str()));
  initctl->AddArg(env.GetForDaemonized());
  std::string command_line = JoinString(argv, ' ');
  initctl->AddArg(base::StringPrintf("COMMANDLINE=%s", command_line.c_str()));
  initctl->RedirectUsingPipe(STDOUT_FILENO, false /* is_input */);

  // Since we're running 'initctl', and not the executable itself,
  // we wait for it to exit.
  initctl->Start();
  std::string output = ReadFromStdout(initctl.get());
  *pid = GetPidFromOutput(output);
  int exit_status = initctl->Wait();
  if (exit_status != 0) {
    LOG(ERROR) << "'initctl start' failed with exit status " << exit_status;
    *pid = -1;
    return false;
  }
  VLOG(1) << "service name " << spec.name() << " pid " << pid;
  names_[*pid] = spec.name();
  return true;
}

bool Launcher::Terminate(pid_t pid) {
  if (pid < 0) {
    LOG(ERROR) << "Invalid pid " << pid;
    return false;
  }

  if (names_.find(pid) == names_.end()) {
    LOG(ERROR) << "Unknown pid " << pid;
    return false;
  }

  std::string name = names_[pid];

  // initctl stop germ_template NAME=<name>
  std::unique_ptr<chromeos::Process> initctl = GetProcessInstance();
  initctl->AddArg("/sbin/initctl");
  initctl->AddArg("stop");
  initctl->AddArg(kSandboxedServiceTemplate);
  initctl->AddArg(base::StringPrintf("NAME=%s", name.c_str()));
  int exit_status = initctl->Run();
  if (exit_status != 0) {
    LOG(ERROR) << "'initctl stop' failed with exit status " << exit_status;
    return false;
  }
  names_.erase(pid);
  return true;
}

pid_t Launcher::GetPidFromOutput(const std::string& output) {
  // germ_template (test) start/running, process 8117
  std::vector<std::string> tokens;
  base::SplitString(output, ' ', &tokens);
  pid_t pid = -1;
  if (tokens.size() < 5 || !base::StringToInt(tokens[4], &pid)) {
    LOG(ERROR) << "Could not extract pid from '" << output << "'";
    return -1;
  }
  return pid;
}

std::string Launcher::ReadFromStdout(chromeos::Process* process) {
  int stdout_fd = process->GetPipe(STDOUT_FILENO);
  char buf[kStdoutBufSize] = {0};
  base::ReadFromFD(stdout_fd, buf, kStdoutBufSize - 1);
  std::string output(buf);
  return output;
}

std::unique_ptr<chromeos::Process> Launcher::GetProcessInstance() {
  std::unique_ptr<chromeos::Process> process(new chromeos::ProcessImpl());
  return process;
}

}  // namespace germ
