// Copyright 2019 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 "debugd/src/scheduler_configuration_tool.h"

#include "debugd/src/error_utils.h"
#include "debugd/src/helper_utils.h"
#include "debugd/src/process_with_output.h"
#include "debugd/src/sandboxed_process.h"

#include <string>

#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_split.h>
#include <base/strings/stringprintf.h>
#include <brillo/errors/error_codes.h>
#include <build/build_config.h>
#include <build/buildflag.h>
#include <chromeos/dbus/service_constants.h>

namespace debugd {

namespace {

constexpr char kErrorPath[] =
    "org.chromium.debugd.SchedulerConfigurationPolicyError";

const char kConservativePolicy[] = "conservative";

const char kPerformancePolicy[] = "performance";

bool IsValidSchedulerPolicy(const std::string& policy) {
  return ((policy == kConservativePolicy) || (policy == kPerformancePolicy));
}

constexpr bool IsX86_64() {
#if defined(__x86_64__)
  return true;
#else
  return false;
#endif
}

// Executes a helper process with the expectation that any message printed to
// stderr indicates a failure that should be passed back over D-Bus.
// Returns false if any errors launching the process occur. Returns true
// otherwise, and sets |exit_status| if it isn't null.
bool RunHelper(const std::string& command,
               const ProcessWithOutput::ArgList& arguments,
               std::string* stdout,
               int* exit_status,
               brillo::ErrorPtr* error) {
  std::string helper_path;
  if (!GetHelperPath(command, &helper_path)) {
    DEBUGD_ADD_ERROR(error, kErrorPath, "Path too long");
    return false;
  }

  // Note: This runs the helper as root and without a sandbox only because the
  // helper immediately drops privileges and enforces its own sandbox. debugd
  // should not be used to launch unsandboxed executables.
  std::string stderr;
  int result = ProcessWithOutput::RunProcess(
      helper_path, arguments, true /*requires_root*/,
      true /* disable_sandbox */, nullptr, stdout, &stderr, error);

  if (!stderr.empty()) {
    DEBUGD_ADD_ERROR(error, kErrorPath, stderr.c_str());
    return false;
  }

  if (exit_status)
    *exit_status = result;
  return true;
}

}  // namespace

bool SchedulerConfigurationTool::SetPolicy(const std::string& policy,
                                           bool lock_policy,
                                           brillo::ErrorPtr* error,
                                           uint32_t* num_cores_disabled) {
  *num_cores_disabled = 0;

  if (!IsX86_64()) {
    DEBUGD_ADD_ERROR(error, kErrorPath, "Invalid architecture");
    return false;
  }

  if (!IsValidSchedulerPolicy(policy)) {
    DEBUGD_ADD_ERROR(error, kErrorPath, "Invalid policy " + policy);
    return false;
  }
  bool is_policy_conservative = (policy == kConservativePolicy);

  if (policy_locked_conservative_) {
    if (is_policy_conservative)
      return true;

    DEBUGD_ADD_ERROR(error, kErrorPath, "Policy locked to conservative");
    return false;
  }

  if (lock_policy && !is_policy_conservative) {
    DEBUGD_ADD_ERROR(error, kErrorPath, "Can't lock performance policy");
    return false;
  }

  int exit_status;
  std::string stdout;
  bool result = RunHelper("scheduler_configuration_helper",
                          ProcessWithOutput::ArgList{"--policy=" + policy},
                          &stdout, &exit_status, error);

  bool status = base::StringToUint(stdout, num_cores_disabled) && result &&
                (exit_status == 0);
  if (!status) {
    DEBUGD_ADD_ERROR(error, kErrorPath,
                     "scheduler_configuration_helper failed: stdout=" + stdout);
  } else {
    // The |policy_locked_conservative_| flag will only be set, if a
    // "conservative" policy was successfully set when it was asked to be
    // locked..
    policy_locked_conservative_ = is_policy_conservative && lock_policy;
  }

  return status;
}

}  // namespace debugd
