// 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 <stddef.h>

#include "tools/gn/build_settings.h"
#include "tools/gn/filesystem_utils.h"
#include "tools/gn/functions.h"
#include "tools/gn/parse_tree.h"
#include "tools/gn/scope.h"
#include "tools/gn/settings.h"
#include "tools/gn/source_dir.h"
#include "tools/gn/source_file.h"
#include "tools/gn/value.h"

namespace functions {

namespace {

// We want the output to match the input in terms of ending in a slash or not.
// Through all the transformations, these can get added or removed in various
// cases.
void MakeSlashEndingMatchInput(const std::string& input, std::string* output) {
  if (EndsWithSlash(input)) {
    if (!EndsWithSlash(*output))  // Preserve same slash type as input.
      output->push_back(input[input.size() - 1]);
  } else {
    if (EndsWithSlash(*output))
      output->resize(output->size() - 1);
  }
}

// Returns true if the given value looks like a directory, otherwise we'll
// assume it's a file.
bool ValueLooksLikeDir(const std::string& value) {
  if (value.empty())
    return true;
  size_t value_size = value.size();

  // Count the number of dots at the end of the string.
  size_t num_dots = 0;
  while (num_dots < value_size && value[value_size - num_dots - 1] == '.')
    num_dots++;

  if (num_dots == value.size())
    return true;  // String is all dots.

  if (IsSlash(value[value_size - num_dots - 1]))
    return true;  // String is a [back]slash followed by 0 or more dots.

  // Anything else.
  return false;
}

Value ConvertOnePath(const Scope* scope,
                     const FunctionCallNode* function,
                     const Value& value,
                     const SourceDir& from_dir,
                     const SourceDir& to_dir,
                     bool convert_to_system_absolute,
                     Err* err) {
  Value result;  // Ensure return value optimization.

  if (!value.VerifyTypeIs(Value::STRING, err))
    return result;
  const std::string& string_value = value.string_value();

  bool looks_like_dir = ValueLooksLikeDir(string_value);

  // System-absolute output special case.
  if (convert_to_system_absolute) {
    base::FilePath system_path;
    if (looks_like_dir) {
      system_path = scope->settings()->build_settings()->GetFullPath(
          from_dir.ResolveRelativeDir(
              value, err,
              scope->settings()->build_settings()->root_path_utf8()));
    } else {
      system_path = scope->settings()->build_settings()->GetFullPath(
          from_dir.ResolveRelativeFile(
              value, err,
              scope->settings()->build_settings()->root_path_utf8()));
    }
    if (err->has_error())
      return Value();

    result = Value(function, FilePathToUTF8(system_path));
    if (looks_like_dir)
      MakeSlashEndingMatchInput(string_value, &result.string_value());
    return result;
  }

  result = Value(function, Value::STRING);
  if (looks_like_dir) {
    result.string_value() = RebasePath(
        from_dir
            .ResolveRelativeDir(
                value, err,
                scope->settings()->build_settings()->root_path_utf8())
            .value(),
        to_dir, scope->settings()->build_settings()->root_path_utf8());
    MakeSlashEndingMatchInput(string_value, &result.string_value());
  } else {
    SourceFile resolved_file = from_dir.ResolveRelativeFile(
        value, err, scope->settings()->build_settings()->root_path_utf8());
    if (err->has_error())
      return Value();
    // Special case:
    //   rebase_path("//foo", "//bar") ==> "../foo"
    //   rebase_path("//foo", "//foo") ==> "." and not "../foo"
    if (resolved_file.value() ==
        to_dir.value().substr(0, to_dir.value().size() - 1)) {
      result.string_value() = ".";
    } else {
      result.string_value() =
          RebasePath(resolved_file.value(), to_dir,
                     scope->settings()->build_settings()->root_path_utf8());
    }
  }

  return result;
}

}  // namespace

const char kRebasePath[] = "rebase_path";
const char kRebasePath_HelpShort[] =
    "rebase_path: Rebase a file or directory to another location.";
const char kRebasePath_Help[] =
    R"(rebase_path: Rebase a file or directory to another location.

  converted = rebase_path(input,
                          new_base = "",
                          current_base = ".")

  Takes a string argument representing a file name, or a list of such strings
  and converts it/them to be relative to a different base directory.

  When invoking the compiler or scripts, GN will automatically convert sources
  and include directories to be relative to the build directory. However, if
  you're passing files directly in the "args" array or doing other manual
  manipulations where GN doesn't know something is a file name, you will need
  to convert paths to be relative to what your tool is expecting.

  The common case is to use this to convert paths relative to the current
  directory to be relative to the build directory (which will be the current
  directory when executing scripts).

  If you want to convert a file path to be source-absolute (that is, beginning
  with a double slash like "//foo/bar"), you should use the get_path_info()
  function. This function won't work because it will always make relative
  paths, and it needs to support making paths relative to the source root, so
  can't also generate source-absolute paths without more special-cases.

Arguments

  input
      A string or list of strings representing file or directory names These
      can be relative paths ("foo/bar.txt"), system absolute paths
      ("/foo/bar.txt"), or source absolute paths ("//foo/bar.txt").

  new_base
      The directory to convert the paths to be relative to. This can be an
      absolute path or a relative path (which will be treated as being relative
      to the current BUILD-file's directory).

      As a special case, if new_base is the empty string (the default), all
      paths will be converted to system-absolute native style paths with system
      path separators. This is useful for invoking external programs.

  current_base
      Directory representing the base for relative paths in the input. If this
      is not an absolute path, it will be treated as being relative to the
      current build file. Use "." (the default) to convert paths from the
      current BUILD-file's directory.

Return value

  The return value will be the same type as the input value (either a string or
  a list of strings). All relative and source-absolute file names will be
  converted to be relative to the requested output System-absolute paths will
  be unchanged.

  Whether an output path will end in a slash will match whether the
  corresponding input path ends in a slash. It will return "." or "./"
  (depending on whether the input ends in a slash) to avoid returning empty
  strings. This means if you want a root path ("//" or "/") not ending in a
  slash, you can add a dot ("//.").

Example

  # Convert a file in the current directory to be relative to the build
  # directory (the current dir when executing compilers and scripts).
  foo = rebase_path("myfile.txt", root_build_dir)
  # might produce "../../project/myfile.txt".

  # Convert a file to be system absolute:
  foo = rebase_path("myfile.txt")
  # Might produce "D:\\source\\project\\myfile.txt" on Windows or
  # "/home/you/source/project/myfile.txt" on Linux.

  # Typical usage for converting to the build directory for a script.
  action("myscript") {
    # Don't convert sources, GN will automatically convert these to be relative
    # to the build directory when it constructs the command line for your
    # script.
    sources = [ "foo.txt", "bar.txt" ]

    # Extra file args passed manually need to be explicitly converted
    # to be relative to the build directory:
    args = [
      "--data",
      rebase_path("//mything/data/input.dat", root_build_dir),
      "--rel",
      rebase_path("relative_path.txt", root_build_dir)
    ] + rebase_path(sources, root_build_dir)
  }
)";

Value RunRebasePath(Scope* scope,
                    const FunctionCallNode* function,
                    const std::vector<Value>& args,
                    Err* err) {
  Value result;

  // Argument indices.
  static const size_t kArgIndexInputs = 0;
  static const size_t kArgIndexDest = 1;
  static const size_t kArgIndexFrom = 2;

  // Inputs.
  if (args.size() < 1 || args.size() > 3) {
    *err = Err(function->function(), "Wrong # of arguments for rebase_path.");
    return result;
  }
  const Value& inputs = args[kArgIndexInputs];

  // To path.
  bool convert_to_system_absolute = true;
  SourceDir to_dir;
  const SourceDir& current_dir = scope->GetSourceDir();
  if (args.size() > kArgIndexDest) {
    if (!args[kArgIndexDest].VerifyTypeIs(Value::STRING, err))
      return result;
    if (!args[kArgIndexDest].string_value().empty()) {
      to_dir = current_dir.ResolveRelativeDir(
          args[kArgIndexDest], err,
          scope->settings()->build_settings()->root_path_utf8());
      if (err->has_error())
        return Value();
      convert_to_system_absolute = false;
    }
  }

  // From path.
  SourceDir from_dir;
  if (args.size() > kArgIndexFrom) {
    if (!args[kArgIndexFrom].VerifyTypeIs(Value::STRING, err))
      return result;
    from_dir = current_dir.ResolveRelativeDir(
        args[kArgIndexFrom], err,
        scope->settings()->build_settings()->root_path_utf8());
    if (err->has_error())
      return Value();
  } else {
    // Default to current directory if unspecified.
    from_dir = current_dir;
  }

  // Path conversion.
  if (inputs.type() == Value::STRING) {
    return ConvertOnePath(scope, function, inputs, from_dir, to_dir,
                          convert_to_system_absolute, err);

  } else if (inputs.type() == Value::LIST) {
    result = Value(function, Value::LIST);
    result.list_value().reserve(inputs.list_value().size());

    for (const auto& input : inputs.list_value()) {
      result.list_value().push_back(
          ConvertOnePath(scope, function, input, from_dir, to_dir,
                         convert_to_system_absolute, err));
      if (err->has_error()) {
        result = Value();
        return result;
      }
    }
    return result;
  }

  *err = Err(function->function(), "rebase_path requires a list or a string.");
  return result;
}

}  // namespace functions
