// Copyright (c) 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 "base/command_line.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_restrictions.h"
#include "base/time/time.h"
#include "build_config.h"
#include "tools/gn/err.h"
#include "tools/gn/exec_process.h"
#include "tools/gn/filesystem_utils.h"
#include "tools/gn/functions.h"
#include "tools/gn/input_conversion.h"
#include "tools/gn/input_file.h"
#include "tools/gn/parse_tree.h"
#include "tools/gn/scheduler.h"
#include "tools/gn/trace.h"
#include "tools/gn/value.h"

namespace functions {

namespace {

bool CheckExecScriptPermissions(const BuildSettings* build_settings,
                                const FunctionCallNode* function,
                                Err* err) {
  const std::set<SourceFile>* whitelist =
      build_settings->exec_script_whitelist();
  if (!whitelist)
    return true;  // No whitelist specified, don't check.

  LocationRange function_range = function->GetRange();
  if (!function_range.begin().file())
    return true;  // No file, might be some internal thing, implicitly pass.

  if (whitelist->find(function_range.begin().file()->name()) !=
      whitelist->end())
    return true;  // Whitelisted, this is OK.

  // Disallowed case.
  *err = Err(function, "Disallowed exec_script call.",
      "The use of exec_script use is restricted in this build. exec_script\n"
      "is discouraged because it can slow down the GN run and is easily\n"
      "abused.\n"
      "\n"
      "Generally nontrivial work should be done as build steps rather than\n"
      "when GN is run. For example, if you need to compute a nontrivial\n"
      "preprocessor define, it will be better to have an action target\n"
      "generate a header containing the define rather than blocking the GN\n"
      "run to compute the value.\n"
      "\n"
      "The allowed callers of exec_script is maintained in the \"//.gn\" file\n"
      "if you need to modify the whitelist.");
  return false;
}

}  // namespace

const char kExecScript[] = "exec_script";
const char kExecScript_HelpShort[] =
    "exec_script: Synchronously run a script and return the output.";
const char kExecScript_Help[] =
    R"(exec_script: Synchronously run a script and return the output.

  exec_script(filename,
              arguments = [],
              input_conversion = "",
              file_dependencies = [])

  Runs the given script, returning the stdout of the script. The build
  generation will fail if the script does not exist or returns a nonzero exit
  code.

  The current directory when executing the script will be the root build
  directory. If you are passing file names, you will want to use the
  rebase_path() function to make file names relative to this path (see "gn help
  rebase_path").

Arguments:

  filename:
      File name of python script to execute. Non-absolute names will be treated
      as relative to the current build file.

  arguments:
      A list of strings to be passed to the script as arguments. May be
      unspecified or the empty list which means no arguments.

  input_conversion:
      Controls how the file is read and parsed. See "gn help input_conversion".

      If unspecified, defaults to the empty string which causes the script
      result to be discarded. exec script will return None.

  dependencies:
      (Optional) A list of files that this script reads or otherwise depends
      on. These dependencies will be added to the build result such that if any
      of them change, the build will be regenerated and the script will be
      re-run.

      The script itself will be an implicit dependency so you do not need to
      list it.

Example

  all_lines = exec_script(
      "myscript.py", [some_input], "list lines",
      [ rebase_path("data_file.txt", root_build_dir) ])

  # This example just calls the script with no arguments and discards the
  # result.
  exec_script("//foo/bar/myscript.py")
)";

class ExecScriptScopedAllowBaseSyncPrimitives
    : public base::ScopedAllowBaseSyncPrimitives {};

Value RunExecScript(Scope* scope,
                    const FunctionCallNode* function,
                    const std::vector<Value>& args,
                    Err* err) {
  if (args.size() < 1 || args.size() > 4) {
    *err = Err(function->function(), "Wrong number of arguments to exec_script",
               "I expected between one and four arguments.");
    return Value();
  }

  const Settings* settings = scope->settings();
  const BuildSettings* build_settings = settings->build_settings();
  const SourceDir& cur_dir = scope->GetSourceDir();

  if (!CheckExecScriptPermissions(build_settings, function, err))
    return Value();

  // Find the python script to run.
  std::string script_source_path = cur_dir.ResolveRelativeAs(
      true, args[0], err,
      scope->settings()->build_settings()->root_path_utf8());
  if (err->has_error())
    return Value();
  base::FilePath script_path =
      build_settings->GetFullPath(script_source_path, true);
  if (!build_settings->secondary_source_path().empty() &&
      !base::PathExists(script_path)) {
    // Fall back to secondary source root when the file doesn't exist.
    script_path =
        build_settings->GetFullPathSecondary(script_source_path, true);
  }

  ScopedTrace trace(TraceItem::TRACE_SCRIPT_EXECUTE, script_source_path);
  trace.SetToolchain(settings->toolchain_label());

  // Add all dependencies of this script, including the script itself, to the
  // build deps.
  g_scheduler->AddGenDependency(script_path);
  if (args.size() == 4) {
    const Value& deps_value = args[3];
    if (!deps_value.VerifyTypeIs(Value::LIST, err))
      return Value();

    for (const auto& dep : deps_value.list_value()) {
      if (!dep.VerifyTypeIs(Value::STRING, err))
        return Value();
      g_scheduler->AddGenDependency(build_settings->GetFullPath(
          cur_dir.ResolveRelativeAs(
              true, dep, err,
              scope->settings()->build_settings()->root_path_utf8()),
          true));
      if (err->has_error())
        return Value();
    }
  }

  // Make the command line.
  const base::FilePath& python_path = build_settings->python_path();
  base::CommandLine cmdline(python_path);

  // CommandLine tries to interpret arguments by default.  Passing "--" disables
  // this for everything following the "--", so pass this as the very first
  // thing to python.  Python ignores a -- before the .py file, and this makes
  // CommandLine let through arguments without modifying them.
  cmdline.AppendArg("--");

  cmdline.AppendArgPath(script_path);

  if (args.size() >= 2) {
    // Optional command-line arguments to the script.
    const Value& script_args = args[1];
    if (!script_args.VerifyTypeIs(Value::LIST, err))
      return Value();
    for (const auto& arg : script_args.list_value()) {
      if (!arg.VerifyTypeIs(Value::STRING, err))
        return Value();
      cmdline.AppendArg(arg.string_value());
    }
  }

  // Log command line for debugging help.
  trace.SetCommandLine(cmdline);
  base::TimeTicks begin_exec;
  if (g_scheduler->verbose_logging()) {
#if defined(OS_WIN)
    g_scheduler->Log("Pythoning",
                     base::UTF16ToUTF8(cmdline.GetCommandLineString()));
#else
    g_scheduler->Log("Pythoning", cmdline.GetCommandLineString());
#endif
    begin_exec = base::TimeTicks::Now();
  }

  base::FilePath startup_dir =
      build_settings->GetFullPath(build_settings->build_dir());
  // The first time a build is run, no targets will have been written so the
  // build output directory won't exist. We need to make sure it does before
  // running any scripts with this as its startup directory, although it will
  // be relatively rare that the directory won't exist by the time we get here.
  //
  // If this shows up on benchmarks, we can cache whether we've done this
  // or not and skip creating the directory.
  base::CreateDirectory(startup_dir);

  // Execute the process.
  // TODO(brettw) set the environment block.
  std::string output;
  std::string stderr_output;
  int exit_code = 0;
  {
    ExecScriptScopedAllowBaseSyncPrimitives allow_base_sync_primitives;
    if (!internal::ExecProcess(cmdline, startup_dir, &output, &stderr_output,
                               &exit_code)) {
      *err = Err(
          function->function(), "Could not execute python.",
          "I was trying to execute \"" + FilePathToUTF8(python_path) + "\".");
      return Value();
    }
  }
  if (g_scheduler->verbose_logging()) {
    g_scheduler->Log(
        "Pythoning",
        script_source_path + " took " +
            base::Int64ToString(
                (base::TimeTicks::Now() - begin_exec).InMilliseconds()) +
            "ms");
  }

  if (exit_code != 0) {
    std::string msg = "Current dir: " + FilePathToUTF8(startup_dir) +
        "\nCommand: " + FilePathToUTF8(cmdline.GetCommandLineString()) +
        "\nReturned " + base::IntToString(exit_code);
    if (!output.empty())
      msg += " and printed out:\n\n" + output;
    else
      msg += ".";
    if (!stderr_output.empty())
      msg += "\nstderr:\n\n" + stderr_output;

    *err = Err(function->function(), "Script returned non-zero exit code.",
               msg);
    return Value();
  }

  // Default to None value for the input conversion if unspecified.
  return ConvertInputToValue(scope->settings(), output, function,
                             args.size() >= 3 ? args[2] : Value(), err);
}

}  // namespace functions
