// 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/time/time.h"
#include "build/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 {
const char kNoExecSwitch[] = "no-exec";
}  // namespace

const char kExecScript[] = "exec_script";
const char kExecScript_HelpShort[] =
    "exec_script: Synchronously run a script and return the output.";
const char kExecScript_Help[] =
    "exec_script: Synchronously run a script and return the output.\n"
    "\n"
    "  exec_script(filename,\n"
    "              arguments = [],\n"
    "              input_conversion = \"\",\n"
    "              file_dependencies = [])\n"
    "\n"
    "  Runs the given script, returning the stdout of the script. The build\n"
    "  generation will fail if the script does not exist or returns a nonzero\n"
    "  exit code.\n"
    "\n"
    "  The current directory when executing the script will be the root\n"
    "  build directory. If you are passing file names, you will want to use\n"
    "  the rebase_path() function to make file names relative to this\n"
    "  path (see \"gn help rebase_path\").\n"
    "\n"
    "Arguments:\n"
    "\n"
    "  filename:\n"
    "      File name of python script to execute. Non-absolute names will\n"
    "      be treated as relative to the current build file.\n"
    "\n"
    "  arguments:\n"
    "      A list of strings to be passed to the script as arguments.\n"
    "      May be unspecified or the empty list which means no arguments.\n"
    "\n"
    "  input_conversion:\n"
    "      Controls how the file is read and parsed.\n"
    "      See \"gn help input_conversion\".\n"
    "\n"
    "      If unspecified, defaults to the empty string which causes the\n"
    "      script result to be discarded. exec script will return None.\n"
    "\n"
    "  dependencies:\n"
    "      (Optional) A list of files that this script reads or otherwise\n"
    "      depends on. These dependencies will be added to the build result\n"
    "      such that if any of them change, the build will be regenerated and\n"
    "      the script will be re-run.\n"
    "\n"
    "      The script itself will be an implicit dependency so you do not\n"
    "      need to list it.\n"
    "\n"
    "Example:\n"
    "\n"
    "  all_lines = exec_script(\n"
    "      \"myscript.py\", [some_input], \"list lines\",\n"
    "      [ rebase_path(\"data_file.txt\", root_build_dir) ])\n"
    "\n"
    "  # This example just calls the script with no arguments and discards\n"
    "  # the result.\n"
    "  exec_script(\"//foo/bar/myscript.py\")\n";

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();

  // Find the python script to run.
  if (!args[0].VerifyTypeIs(Value::STRING, err))
    return Value();
  SourceFile script_source =
      cur_dir.ResolveRelativeFile(args[0].string_value(),
          scope->settings()->build_settings()->root_path_utf8());
  base::FilePath script_path = build_settings->GetFullPath(script_source);
  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);
  }

  ScopedTrace trace(TraceItem::TRACE_SCRIPT_EXECUTE, script_source.value());
  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.ResolveRelativeFile(
              dep.string_value(),
              scope->settings()->build_settings()->root_path_utf8())));
    }
  }

  // Make the command line.
  const base::FilePath& python_path = build_settings->python_path();
  CommandLine cmdline(python_path);
  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;
  if (!CommandLine::ForCurrentProcess()->HasSwitch(kNoExecSwitch)) {
    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.value() + " 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
