/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "exec_utils.h"

#include <poll.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

#include <ctime>
#include <string_view>

#ifdef __BIONIC__
#include <sys/pidfd.h>
#endif

#include <chrono>
#include <climits>
#include <condition_variable>
#include <cstdint>
#include <mutex>
#include <string>
#include <thread>
#include <vector>

#include "android-base/file.h"
#include "android-base/parseint.h"
#include "android-base/scopeguard.h"
#include "android-base/stringprintf.h"
#include "android-base/strings.h"
#include "android-base/unique_fd.h"
#include "base/macros.h"
#include "base/utils.h"
#include "runtime.h"

namespace art {

namespace {

using ::android::base::ParseInt;
using ::android::base::ReadFileToString;
using ::android::base::StringPrintf;
using ::android::base::unique_fd;

std::string ToCommandLine(const std::vector<std::string>& args) {
  return android::base::Join(args, ' ');
}

// Fork and execute a command specified in a subprocess.
// If there is a runtime (Runtime::Current != nullptr) then the subprocess is created with the
// same environment that existed when the runtime was started.
// Returns the process id of the child process on success, -1 otherwise.
pid_t ExecWithoutWait(const std::vector<std::string>& arg_vector, std::string* error_msg) {
  // Convert the args to char pointers.
  const char* program = arg_vector[0].c_str();
  std::vector<char*> args;
  for (const auto& arg : arg_vector) {
    args.push_back(const_cast<char*>(arg.c_str()));
  }
  args.push_back(nullptr);

  // fork and exec
  pid_t pid = fork();
  if (pid == 0) {
    // no allocation allowed between fork and exec

    // change process groups, so we don't get reaped by ProcessManager
    setpgid(0, 0);

    // (b/30160149): protect subprocesses from modifications to LD_LIBRARY_PATH, etc.
    // Use the snapshot of the environment from the time the runtime was created.
    char** envp = (Runtime::Current() == nullptr) ? nullptr : Runtime::Current()->GetEnvSnapshot();
    if (envp == nullptr) {
      execv(program, &args[0]);
    } else {
      execve(program, &args[0], envp);
    }
    // This should be regarded as a crash rather than a normal return.
    PLOG(FATAL) << "Failed to execute (" << ToCommandLine(arg_vector) << ")";
    UNREACHABLE();
  } else if (pid == -1) {
    *error_msg = StringPrintf("Failed to execute (%s) because fork failed: %s",
                              ToCommandLine(arg_vector).c_str(),
                              strerror(errno));
    return -1;
  } else {
    return pid;
  }
}

ExecResult WaitChild(pid_t pid,
                     const std::vector<std::string>& arg_vector,
                     bool no_wait,
                     std::string* error_msg) {
  siginfo_t info;
  // WNOWAIT leaves the child in a waitable state. The call is still blocking.
  int options = WEXITED | (no_wait ? WNOWAIT : 0);
  if (TEMP_FAILURE_RETRY(waitid(P_PID, pid, &info, options)) != 0) {
    *error_msg = StringPrintf("waitid failed for (%s) pid %d: %s",
                              ToCommandLine(arg_vector).c_str(),
                              pid,
                              strerror(errno));
    return {.status = ExecResult::kUnknown};
  }
  if (info.si_pid != pid) {
    *error_msg = StringPrintf("waitid failed for (%s): wanted pid %d, got %d: %s",
                              ToCommandLine(arg_vector).c_str(),
                              pid,
                              info.si_pid,
                              strerror(errno));
    return {.status = ExecResult::kUnknown};
  }
  if (info.si_code != CLD_EXITED) {
    *error_msg =
        StringPrintf("Failed to execute (%s) because the child process is terminated by signal %d",
                     ToCommandLine(arg_vector).c_str(),
                     info.si_status);
    return {.status = ExecResult::kSignaled, .signal = info.si_status};
  }
  return {.status = ExecResult::kExited, .exit_code = info.si_status};
}

// A fallback implementation of `WaitChildWithTimeout` that creates a thread to wait instead of
// relying on `pidfd_open`.
ExecResult WaitChildWithTimeoutFallback(pid_t pid,
                                        const std::vector<std::string>& arg_vector,
                                        int timeout_ms,
                                        std::string* error_msg) {
  bool child_exited = false;
  bool timed_out = false;
  std::condition_variable cv;
  std::mutex m;

  std::thread wait_thread([&]() {
    std::unique_lock<std::mutex> lock(m);
    if (!cv.wait_for(lock, std::chrono::milliseconds(timeout_ms), [&] { return child_exited; })) {
      timed_out = true;
      kill(pid, SIGKILL);
    }
  });

  ExecResult result = WaitChild(pid, arg_vector, /*no_wait=*/true, error_msg);

  {
    std::unique_lock<std::mutex> lock(m);
    child_exited = true;
  }
  cv.notify_all();
  wait_thread.join();

  // The timeout error should have a higher priority than any other error.
  if (timed_out) {
    *error_msg =
        StringPrintf("Failed to execute (%s) because the child process timed out after %dms",
                     ToCommandLine(arg_vector).c_str(),
                     timeout_ms);
    return ExecResult{.status = ExecResult::kTimedOut};
  }

  return result;
}

// Waits for the child process to finish and leaves the child in a waitable state.
ExecResult WaitChildWithTimeout(pid_t pid,
                                unique_fd pidfd,
                                const std::vector<std::string>& arg_vector,
                                int timeout_ms,
                                std::string* error_msg) {
  auto cleanup = android::base::make_scope_guard([&]() {
    kill(pid, SIGKILL);
    std::string ignored_error_msg;
    WaitChild(pid, arg_vector, /*no_wait=*/true, &ignored_error_msg);
  });

  struct pollfd pfd;
  pfd.fd = pidfd.get();
  pfd.events = POLLIN;
  int poll_ret = TEMP_FAILURE_RETRY(poll(&pfd, /*nfds=*/1, timeout_ms));

  pidfd.reset();

  if (poll_ret < 0) {
    *error_msg = StringPrintf("poll failed for pid %d: %s", pid, strerror(errno));
    return {.status = ExecResult::kUnknown};
  }
  if (poll_ret == 0) {
    *error_msg =
        StringPrintf("Failed to execute (%s) because the child process timed out after %dms",
                     ToCommandLine(arg_vector).c_str(),
                     timeout_ms);
    return {.status = ExecResult::kTimedOut};
  }

  cleanup.Disable();
  return WaitChild(pid, arg_vector, /*no_wait=*/true, error_msg);
}

bool ParseProcStat(const std::string& stat_content,
                   int64_t uptime_ms,
                   int64_t ticks_per_sec,
                   /*out*/ ProcessStat* stat) {
  size_t pos = stat_content.rfind(") ");
  if (pos == std::string::npos) {
    return false;
  }
  std::vector<std::string> stat_fields;
  // Skip the first two fields. The second field is the parenthesized process filename, which can
  // contain anything, including spaces.
  Split(std::string_view(stat_content).substr(pos + 2), ' ', &stat_fields);
  constexpr int kSkippedFields = 2;
  int64_t utime, stime, cutime, cstime, starttime;
  if (stat_fields.size() < 22 - kSkippedFields ||
      !ParseInt(stat_fields[13 - kSkippedFields], &utime) ||
      !ParseInt(stat_fields[14 - kSkippedFields], &stime) ||
      !ParseInt(stat_fields[15 - kSkippedFields], &cutime) ||
      !ParseInt(stat_fields[16 - kSkippedFields], &cstime) ||
      !ParseInt(stat_fields[21 - kSkippedFields], &starttime)) {
    return false;
  }
  stat->cpu_time_ms = (utime + stime + cutime + cstime) * 1000 / ticks_per_sec;
  stat->wall_time_ms = uptime_ms - starttime * 1000 / ticks_per_sec;
  return true;
}

}  // namespace

int ExecUtils::ExecAndReturnCode(const std::vector<std::string>& arg_vector,
                                 std::string* error_msg) const {
  return ExecAndReturnResult(arg_vector, /*timeout_sec=*/-1, error_msg).exit_code;
}

ExecResult ExecUtils::ExecAndReturnResult(const std::vector<std::string>& arg_vector,
                                          int timeout_sec,
                                          std::string* error_msg) const {
  return ExecAndReturnResult(arg_vector, timeout_sec, ExecCallbacks(), /*stat=*/nullptr, error_msg);
}

ExecResult ExecUtils::ExecAndReturnResult(const std::vector<std::string>& arg_vector,
                                          int timeout_sec,
                                          const ExecCallbacks& callbacks,
                                          /*out*/ ProcessStat* stat,
                                          /*out*/ std::string* error_msg) const {
  if (timeout_sec > INT_MAX / 1000) {
    *error_msg = "Timeout too large";
    return {.status = ExecResult::kStartFailed};
  }

  // Start subprocess.
  pid_t pid = ExecWithoutWait(arg_vector, error_msg);
  if (pid == -1) {
    return {.status = ExecResult::kStartFailed};
  }

  callbacks.on_start(pid);

  // Wait for subprocess to finish.
  ExecResult result;
  if (timeout_sec >= 0) {
    unique_fd pidfd = PidfdOpen(pid);
    if (pidfd.get() >= 0) {
      result =
          WaitChildWithTimeout(pid, std::move(pidfd), arg_vector, timeout_sec * 1000, error_msg);
    } else {
      LOG(DEBUG) << StringPrintf(
          "pidfd_open failed for pid %d: %s, falling back", pid, strerror(errno));
      result = WaitChildWithTimeoutFallback(pid, arg_vector, timeout_sec * 1000, error_msg);
    }
  } else {
    result = WaitChild(pid, arg_vector, /*no_wait=*/true, error_msg);
  }

  if (stat != nullptr) {
    std::string local_error_msg;
    if (!GetStat(pid, stat, &local_error_msg)) {
      LOG(ERROR) << "Failed to get process stat: " << local_error_msg;
    }
  }

  callbacks.on_end(pid);

  std::string local_error_msg;
  // TODO(jiakaiz): Use better logic to detect waitid failure.
  if (WaitChild(pid, arg_vector, /*no_wait=*/false, &local_error_msg).status ==
      ExecResult::kUnknown) {
    LOG(ERROR) << "Failed to clean up child process '" << arg_vector[0] << "': " << local_error_msg;
  }

  return result;
}

bool ExecUtils::Exec(const std::vector<std::string>& arg_vector, std::string* error_msg) const {
  int status = ExecAndReturnCode(arg_vector, error_msg);
  if (status < 0) {
    // Internal error. The error message is already set.
    return false;
  }
  if (status > 0) {
    *error_msg =
        StringPrintf("Failed to execute (%s) because the child process returns non-zero exit code",
                     ToCommandLine(arg_vector).c_str());
    return false;
  }
  return true;
}

unique_fd ExecUtils::PidfdOpen(pid_t pid) const {
#ifdef __BIONIC__
  return unique_fd(pidfd_open(pid, /*flags=*/0));
#else
  // There is no glibc wrapper for pidfd_open.
#ifndef SYS_pidfd_open
  constexpr int SYS_pidfd_open = 434;
#endif
  return unique_fd(syscall(SYS_pidfd_open, pid, /*flags=*/0));
#endif
}

std::string ExecUtils::GetProcStat(pid_t pid) const {
  std::string stat_content;
  if (!ReadFileToString(StringPrintf("/proc/%d/stat", pid), &stat_content)) {
    stat_content = "";
  }
  return stat_content;
}

int64_t ExecUtils::GetUptimeMs() const {
  timespec t;
  clock_gettime(CLOCK_MONOTONIC, &t);
  return t.tv_sec * 1000 + t.tv_nsec / 1000000;
}

int64_t ExecUtils::GetTicksPerSec() const { return sysconf(_SC_CLK_TCK); }

bool ExecUtils::GetStat(pid_t pid,
                        /*out*/ ProcessStat* stat,
                        /*out*/ std::string* error_msg) const {
  int64_t uptime_ms = GetUptimeMs();
  std::string stat_content = GetProcStat(pid);
  if (stat_content.empty()) {
    *error_msg = StringPrintf("Failed to read /proc/%d/stat: %s", pid, strerror(errno));
    return false;
  }
  int64_t ticks_per_sec = GetTicksPerSec();
  if (!ParseProcStat(stat_content, uptime_ms, ticks_per_sec, stat)) {
    *error_msg = StringPrintf("Failed to parse /proc/%d/stat '%s'", pid, stat_content.c_str());
    return false;
  }
  return true;
}

}  // namespace art
