// Copyright 2014 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 "gn/err.h"
#include "gn/functions.h"
#include "gn/parse_tree.h"
#include "gn/scope.h"

namespace functions {

namespace {

void ForwardAllValues(const FunctionCallNode* function,
                      Scope* source,
                      Scope* dest,
                      const std::set<std::string>& exclusion_set,
                      Err* err) {
  Scope::MergeOptions options;
  // This function needs to clobber existing for it to be useful. It will be
  // called in a template to forward all values, but there will be some
  // default stuff like configs set up in both scopes, so it would always
  // fail if it didn't clobber.
  options.clobber_existing = true;
  options.skip_private_vars = true;
  options.mark_dest_used = false;
  options.excluded_values = exclusion_set;
  source->NonRecursiveMergeTo(dest, options, function, "source scope", err);
  source->MarkAllUsed();
}

void ForwardValuesFromList(Scope* source,
                           Scope* dest,
                           const std::vector<Value>& list,
                           const std::set<std::string>& exclusion_set,
                           Err* err) {
  for (const Value& cur : list) {
    if (!cur.VerifyTypeIs(Value::STRING, err))
      return;
    if (exclusion_set.find(cur.string_value()) != exclusion_set.end())
      continue;
    const Value* value = source->GetValue(cur.string_value(), true);
    if (value) {
      // Use the storage key for the original value rather than the string in
      // "cur" because "cur" is a temporary that will be deleted, and Scopes
      // expect a persistent std::string_view (it won't copy). Not doing this
      // will lead the scope's key to point to invalid memory after this
      // returns.
      std::string_view storage_key = source->GetStorageKey(cur.string_value());
      if (storage_key.empty()) {
        // Programmatic value, don't allow copying.
        *err =
            Err(cur, "This value can't be forwarded.",
                "The variable \"" + cur.string_value() + "\" is a built-in.");
        return;
      }

      // Don't allow clobbering existing values.
      const Value* existing_value = dest->GetValue(storage_key);
      if (existing_value) {
        *err = Err(
            cur, "Clobbering existing value.",
            "The current scope already defines a value \"" +
                cur.string_value() +
                "\".\nforward_variables_from() won't clobber "
                "existing values. If you want to\nmerge lists, you'll need to "
                "do this explicitly.");
        err->AppendSubErr(Err(*existing_value, "value being clobbered."));
        return;
      }

      // Keep the origin information from the original value. The normal
      // usage is for this to be used in a template, and if there's an error,
      // the user expects to see the line where they set the variable
      // blamed, rather than a template call to forward_variables_from().
      dest->SetValue(storage_key, *value, value->origin());
    }
  }
}

}  // namespace

const char kForwardVariablesFrom[] = "forward_variables_from";
const char kForwardVariablesFrom_HelpShort[] =
    "forward_variables_from: Copies variables from a different scope.";
const char kForwardVariablesFrom_Help[] =
    R"(forward_variables_from: Copies variables from a different scope.

  forward_variables_from(from_scope, variable_list_or_star,
                         variable_to_not_forward_list = [])

  Copies the given variables from the given scope to the local scope if they
  exist. This is normally used in the context of templates to use the values of
  variables defined in the template invocation to a template-defined target.

  The variables in the given variable_list will be copied if they exist in the
  given scope or any enclosing scope. If they do not exist, nothing will happen
  and they be left undefined in the current scope.

  As a special case, if the variable_list is a string with the value of "*",
  all variables from the given scope will be copied. "*" only copies variables
  set directly on the from_scope, not enclosing ones. Otherwise it would
  duplicate all global variables.

  When an explicit list of variables is supplied, if the variable exists in the
  current (destination) scope already, an error will be thrown. If "*" is
  specified, variables in the current scope will be clobbered (the latter is
  important because most targets have an implicit configs list, which means it
  wouldn't work at all if it didn't clobber).

  If variables_to_not_forward_list is non-empty, then it must contains a list
  of variable names that will not be forwarded. This is mostly useful when
  variable_list_or_star has a value of "*".

Examples

  # forward_variables_from(invoker, ["foo"])
  # is equivalent to:
  assert(!defined(foo))
  if (defined(invoker.foo)) {
    foo = invoker.foo
  }

  # This is a common action template. It would invoke a script with some given
  # parameters, and wants to use the various types of deps and the visibility
  # from the invoker if it's defined. It also injects an additional dependency
  # to all targets.
  template("my_test") {
    action(target_name) {
      forward_variables_from(invoker, [ "data_deps", "deps",
                                        "public_deps", "visibility"])
      # Add our test code to the dependencies.
      # "deps" may or may not be defined at this point.
      if (defined(deps)) {
        deps += [ "//tools/doom_melon" ]
      } else {
        deps = [ "//tools/doom_melon" ]
      }
    }
  }

  # This is a template around a target whose type depends on a global variable.
  # It forwards all values from the invoker.
  template("my_wrapper") {
    target(my_wrapper_target_type, target_name) {
      forward_variables_from(invoker, "*")
    }
  }

  # A template that wraps another. It adds behavior based on one
  # variable, and forwards all others to the nested target.
  template("my_ios_test_app") {
    ios_test_app(target_name) {
      forward_variables_from(invoker, "*", ["test_bundle_name"])
      if (!defined(extra_substitutions)) {
        extra_substitutions = []
      }
      extra_substitutions += [ "BUNDLE_ID_TEST_NAME=$test_bundle_name" ]
    }
  }
)";

// This function takes a ListNode rather than a resolved vector of values
// both avoid copying the potentially-large source scope, and so the variables
// in the source scope can be marked as used.
Value RunForwardVariablesFrom(Scope* scope,
                              const FunctionCallNode* function,
                              const ListNode* args_list,
                              Err* err) {
  const auto& args_vector = args_list->contents();
  if (args_vector.size() != 2 && args_vector.size() != 3) {
    *err = Err(function, "Wrong number of arguments.",
               "Expecting two or three arguments.");
    return Value();
  }

  Value* value = nullptr;  // Value to use, may point to result_value.
  Value result_value;      // Storage for the "evaluate" case.
  const IdentifierNode* identifier = args_vector[0]->AsIdentifier();
  if (identifier) {
    // Optimize the common case where the input scope is an identifier. This
    // prevents a copy of a potentially large Scope object.
    value = scope->GetMutableValue(identifier->value().value(),
                                   Scope::SEARCH_NESTED, true);
    if (!value) {
      *err = Err(identifier, "Undefined identifier.");
      return Value();
    }
  } else {
    // Non-optimized case, just evaluate the argument.
    result_value = args_vector[0]->Execute(scope, err);
    if (err->has_error())
      return Value();
    value = &result_value;
  }

  // Extract the source scope.
  if (!value->VerifyTypeIs(Value::SCOPE, err))
    return Value();
  Scope* source = value->scope_value();

  // Extract the exclusion list if defined.
  std::set<std::string> exclusion_set;
  if (args_vector.size() == 3) {
    Value exclusion_value = args_vector[2]->Execute(scope, err);
    if (err->has_error())
      return Value();

    if (exclusion_value.type() != Value::LIST) {
      *err = Err(exclusion_value, "Not a valid list of variables to exclude.",
                 "Expecting a list of strings.");
      return Value();
    }

    for (const Value& cur : exclusion_value.list_value()) {
      if (!cur.VerifyTypeIs(Value::STRING, err))
        return Value();

      exclusion_set.insert(cur.string_value());
    }
  }

  // Extract the list. If all_values is not set, the what_value will be a list.
  Value what_value = args_vector[1]->Execute(scope, err);
  if (err->has_error())
    return Value();
  if (what_value.type() == Value::STRING) {
    if (what_value.string_value() == "*") {
      ForwardAllValues(function, source, scope, exclusion_set, err);
      return Value();
    }
  } else {
    if (what_value.type() == Value::LIST) {
      ForwardValuesFromList(source, scope, what_value.list_value(),
                            exclusion_set, err);
      return Value();
    }
  }

  // Not the right type of argument.
  *err = Err(what_value, "Not a valid list of variables to copy.",
             "Expecting either the string \"*\" or a list of strings.");
  return Value();
}

}  // namespace functions
