// Copyright 2026 The GN 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/edit_subcommands.h"

#include <optional>
#include <set>
#include <string>
#include <utility>
#include <vector>

#include "base/containers/span.h"
#include "base/strings/string_number_conversions.h"
#include "gn/build_file_editor.h"
#include "gn/err.h"
#include "gn/location.h"
#include "gn/parse_tree.h"
#include "gn/value.h"

namespace {

// Parses a single string argument into a primitive GN Value (bool, int, or
// string).
Result<Value> ParseValue(std::string_view val_string) {
  if (val_string == "true") {
    return Value(nullptr, true);
  }
  if (val_string == "false") {
    return Value(nullptr, false);
  }

  int64_t result_int;
  if (base::StringToInt64(val_string, &result_int)) {
    return Value(nullptr, result_int);
  }

  return Value(nullptr, std::string(val_string));
}

// Parses multiple string arguments into a vector of GN Values.
Result<std::vector<Value>> ParseValues(base::span<const std::string> values) {
  std::vector<Value> list_elements;
  list_elements.reserve(values.size());
  for (const std::string& val_str : values) {
    ASSIGN_OR_RETURN(Value val, ParseValue(val_str));
    list_elements.push_back(std::move(val));
  }
  return list_elements;
}

const TreeNode* FirstUnconditionalAssignment(
    const std::vector<TreeNode>& assignments) {
  for (const auto& assignment : assignments) {
    if (!assignment.is_conditional() && assignment.AsAssignment())
      return &assignment;
  }
  return nullptr;
}

// Helper to create an EditCommand that loops over all matched targets in a
// BuildFile.
EditCommand EditTargetCommand(
    std::function<Err(BuildFile&, const EditTarget&, EditState&)>
        apply_to_target) {
  return [apply_to_target = std::move(apply_to_target)](
             BuildFile& build_file, EditState& state) -> Err {
    for (const auto& target : build_file.targets()) {
      RETURN_IF_ERROR(apply_to_target(build_file, target, state));
    }
    return Ok();
  };
}

bool RemoveFromTarget(const EditTarget& target,
                      const std::string& attribute,
                      const Value& value,
                      EditState& state) {
  bool done = false;
  for (auto& assignment : target.assignments(attribute)) {
    auto matches = FindListElementInAssignment(target, assignment, value);

    for (const auto& match : matches) {
      match.RemoveSelf(state, target);
    }
    done |= !matches.empty();
  }

  if (!done && target.is_explicit) {
    target.add_warning(state, "does not contain the value " +
                                  value.ToString(true) + " in attribute \"" +
                                  attribute + "\".");
  }
  return done;
}

void AddToTarget(BuildFile& build_file,
                 const EditTarget& target,
                 const std::string& attribute,
                 const std::vector<Value>& values) {
  auto assignments = target.assignments(attribute);
  std::vector<Value> to_add = values;

  // Iterate over a copy of values since we're mutating it.
  for (const auto& value : values) {
    for (auto& assignment : assignments) {
      auto matches = FindListElementInAssignment(target, assignment, value);
      for (const auto& match : matches) {
        if (assignment.is_conditional()) {
          // If it's assigned conditionally, remove it from the list first,
          // since we're going to assign it unconditionally.
          // Unlike usual we don't mark this with a comment, because this is
          // safe.
          match.RemoveSelfUnconditionally();
        } else {
          // If it's added unconditionally, we don't need to worry about
          // adding it anymore.
          std::erase(to_add, value);
        }
      }
    }
  }

  if (const auto* first = FirstUnconditionalAssignment(assignments); first) {
    // Case A: There exists an unconditional assignment -> add values to it.
    ListNode* target_list = nullptr;
    if (auto list = FindListInAssignment(*first)) {
      // The expression is something like `[ "a" ]` or `foo + [ "a" ]`
      // In this case we just add directly to the first list "literal" we
      // find.
      target_list = *list;
    } else {
      // The expression doesn't have a list literal (eg. `foo`)
      // Rewrite it as `[] + foo` so we can add to the empty list.
      auto* op = first->AsAssignment();
      auto empty_list_val =
          build_file.to_node(Value(nullptr, std::vector<Value>{}));
      target_list = empty_list_val->AsListMut();

      auto plus_node = std::make_unique<BinaryOpNode>();
      plus_node->set_op(Token(build_file.location(), Token::PLUS, "+"));
      plus_node->set_left(std::move(empty_list_val));
      plus_node->set_right(op->take_right());

      op->set_right(std::move(plus_node));
    }

    for (const auto& value : to_add) {
      target_list->append_item(build_file.to_node(value));
    }
  } else if (!assignments.empty()) {
    // Case B: attr is only defined conditionally -> add attr = [value] at the
    // start of the block, change all other assignments to "+=".
    for (auto& assignment : assignments) {
      if (auto* op = assignment->AsBinaryOpMut()) {
        if (op->op().type() == Token::EQUAL) {
          op->set_op(Token(op->op().location(), Token::PLUS_EQUALS, "+="));
        }
      }
    }
    target.block->statements().insert(
        target.block->statements().begin(),
        build_file.create_assignment(
            attribute,
            build_file.to_node(Value(nullptr, std::vector<Value>(to_add)))));
  } else {
    // Case C: attr is not defined -> add attr = [value] at the end of the
    // block.
    target.block->append_statement(build_file.create_assignment(
        attribute,
        build_file.to_node(Value(nullptr, std::vector<Value>(to_add)))));
  }
}

EditCommand AddToAttributeCommand(std::string attribute,
                                  std::vector<Value> values) {
  return EditTargetCommand(
      [attribute = std::move(attribute), values = std::move(values)](
          BuildFile& build_file, const EditTarget& target,
          EditState& state) -> Err {
        AddToTarget(build_file, target, attribute, values);
        return Ok();
      });
}
EditCommand DeleteCommand() {
  return EditTargetCommand([](BuildFile& build_file, const EditTarget& target,
                              EditState& state) -> Err {
    target.node.RemoveSelf(state, target);
    return Ok();
  });
}

EditCommand MoveCommand(std::string from_attribute,
                        std::string to_attribute,
                        std::vector<Value> values) {
  return EditTargetCommand([from_attribute = std::move(from_attribute),
                            to_attribute = std::move(to_attribute),
                            values = std::move(values)](
                               BuildFile& build_file, const EditTarget& target,
                               EditState& state) -> Err {
    std::vector<Value> moved_values;
    for (const auto& value : values) {
      if (RemoveFromTarget(target, from_attribute, value, state)) {
        moved_values.push_back(value);
      }
    }
    if (!moved_values.empty()) {
      AddToTarget(build_file, target, to_attribute, moved_values);
    }
    return Ok();
  });
}

using LocationProvider =
    std::function<Result<TreeNode::NodeLocation>(BuildFile&)>;

EditCommand NewCommand(std::string rule_kind,
                       LocationProvider location_provider) {
  return [rule_kind = std::move(rule_kind),
          location_provider = std::move(location_provider)](
             BuildFile& build_file, EditState& state) -> Err {
    ASSIGN_OR_RETURN(auto rule_names,
                     build_file.label_matcher().explicit_target_names());
    DCHECK(!rule_names.empty());

    ASSIGN_OR_RETURN(auto loc, location_provider(build_file));
    auto& [container, it] = loc;

    for (const auto& rule_name : rule_names) {
      if (auto target = build_file.find_target(rule_name);
          target && !target->node.is_conditional()) {
        return Err(Location(), "Target \"" + rule_name +
                                   "\" already exists in " +
                                   build_file.source_file().value() + ".");
      }

      // Reassign and advance the iterator returned by insert() to ensure valid
      // iterators across vector reallocations and preserve insertion order
      // when adding multiple targets.
      it = container.insert(
          it, build_file.create_target(rule_kind, rule_name,
                                       build_file.create_block()));
      ++it;
    }
    return Ok();
  };
}

EditCommand RemoveAttributeCommand(std::string attribute) {
  return EditTargetCommand([attribute = std::move(attribute)](
                               BuildFile& build_file, const EditTarget& target,
                               EditState& state) -> Err {
    auto assignments = target.assignments(attribute);
    for (auto& assignment : assignments) {
      assignment.RemoveSelf(state, target);
    }
    if (assignments.empty() && target.is_explicit) {
      target.add_warning(
          state, "does not contain the attribute \"" + attribute + "\".");
    }
    return Ok();
  });
}

EditCommand RemoveFromAttributeCommand(std::string attribute,
                                       std::vector<Value> values) {
  return EditTargetCommand(
      [attribute = std::move(attribute), values = std::move(values)](
          BuildFile& build_file, const EditTarget& target,
          EditState& state) -> Err {
        for (const auto& value : values) {
          RemoveFromTarget(target, attribute, value, state);
        }
        return Ok();
      });
}

EditCommand RenameAttributeCommand(std::string_view from_attribute,
                                   std::string_view to_attribute) {
  return EditTargetCommand([from_attribute = std::string(from_attribute),
                            to_attribute = std::string(to_attribute)](
                               BuildFile& build_file, const EditTarget& target,
                               EditState& state) -> Err {
    auto assignments = target.assignments(from_attribute);
    for (auto& assignment : assignments) {
      assignment->AsBinaryOpMut()->set_left(
          build_file.create_identifier(to_attribute));
    }
    if (assignments.empty() && target.is_explicit) {
      target.add_warning(
          state, "does not contain the attribute \"" + from_attribute + "\".");
    }
    return Ok();
  });
}

// Sets an attribute to a value.
EditCommand SetCommand(std::string attribute, Value value) {
  return EditTargetCommand([=](BuildFile& build_file, const EditTarget& target,
                               EditState& state) -> Err {
    auto assignments = target.assignments(attribute);
    const auto* first = FirstUnconditionalAssignment(assignments);
    for (const auto& assignment : assignments) {
      if (&assignment != first) {
        assignment.RemoveSelf(state, target);
      }
    }

    if (first) {
      (*first)->AsBinaryOpMut()->set_right(build_file.to_node(value));
    } else {
      target.block->append_statement(
          build_file.create_assignment(attribute, build_file.to_node(value)));
    }

    return Ok();
  });
}

Result<std::string> GetShardName(const LocationRange& location,
                                 std::string_view path) {
  if (path.empty() || path.starts_with("/")) {
    return Err(
        location,
        "Cannot shard target with non-relative source path: " +
            std::string(path),
        "Determining a shard name is not supported for non-relative paths.");
  }
  if (path.starts_with("./")) {
    path.remove_prefix(2);
  }

  size_t last_slash = path.rfind('/');
  size_t last_dot = path.rfind('.');
  if (last_dot != std::string_view::npos &&
      (last_slash == std::string_view::npos || last_dot > last_slash)) {
    path = path.substr(0, last_dot);
  }

  std::string shard_name;
  shard_name.reserve(path.size());
  for (char c : path) {
    if (c == '/' || c == '\\' || c == '.' || c == '-') {
      shard_name.push_back('_');
    } else {
      shard_name.push_back(c);
    }
  }
  return shard_name;
}

EditCommand ShardCommand(
    std::optional<std::string> shard_target_type = std::nullopt,
    std::string group_type = "group") {
  return EditTargetCommand([shard_target_type, group_type](
                               BuildFile& build_file, const EditTarget& target,
                               EditState& state) -> Err {
    std::set<std::string> shards;
    for (auto assign : target.assignments({"sources", "public"})) {
      for (const auto& item : FindAllListElements(assign)) {
        if (auto lit = AsStringLiteral(item.node()); lit) {
          ASSIGN_OR_RETURN(std::string shard_name,
                           GetShardName(item->GetRange(), *lit));
          shards.insert(std::move(shard_name));
        }
      }
    }

    if (shards.size() <= 1) {
      target.add_warning(state, "does not need to be sharded.");
      return Ok();
    }

    for (auto assign : target.assignments({"public_deps", "deps"})) {
      assign.RemoveSelfUnconditionally();
    }

    std::vector<Value> target_names;
    auto [container, it] = target.node.node_location();
    // Ensure we insert the shard after the group.
    ++it;

    for (const auto& shard : shards) {
      // Note: If a target "foo" contains both "foo.cc" and "foo_foo.cc", both
      // would map to "foo_foo". This is a rare edge case that is not worth
      // complex disambiguation logic.
      std::string target_name = (shard == target.label.name())
                                    ? (target.label.name() + "_" + shard)
                                    : shard;
      target_names.push_back(Value(nullptr, ":" + target_name));
      state.needs_fix_deps.insert(Label(target.label.dir(), target_name));

      auto node = target.node.node()->Clone();
      auto* func = node->AsFunctionCallMut();
      if (shard_target_type) {
        func->set_function(Token(func->function().location(), Token::IDENTIFIER,
                                 *shard_target_type));
      }
      it = container.insert(it, std::move(node));
      ++it;

      func->args()->contents()[0] =
          build_file.to_node(Value(nullptr, target_name));

      for (auto assign :
           TreeNode({func->block()}).assignments({"sources", "public"})) {
        for (const auto& item : FindAllListElements(assign)) {
          if (auto lit = AsStringLiteral(item.node()); lit) {
            auto res = GetShardName(item->GetRange(), *lit);
            DCHECK(!res.has_error()) << "should have failed above";
            if (*res != shard) {
              item.RemoveSelfUnconditionally();
            }
          }
        }
      }
    }

    auto* orig_func = target.node.node()->AsFunctionCallMut();
    orig_func->set_function(
        Token(orig_func->function().location(), Token::IDENTIFIER, group_type));

    std::vector<std::unique_ptr<ParseNode>> group_stmts;
    group_stmts.push_back(build_file.create_assignment(
        "public_deps",
        build_file.to_node(Value(nullptr, std::move(target_names)))));
    for (const auto& assign : target.assignments({"testonly", "visibility"})) {
      auto node = assign.node()->Clone();
      if (assign.is_conditional()) {
        TreeNode({node.get()})
            .add_todo(
                state, target,
                "This was conditional in the original target. Manual review is "
                "required to decide if it applies to this group target.");
      }
      group_stmts.push_back(std::move(node));
    }

    target.block->statements() = std::move(group_stmts);
    return Ok();
  });
}

}  // namespace

Result<EditCommand> ParseCommand(std::vector<std::string> args) {
  if (args.empty()) {
    return Err(Location(), "Empty command.");
  }

  if (args[0] == "add") {
    if (args.size() < 3) {
      return Err(Location(), "Invalid add command.",
                 "Usage: add <attribute> <value(s)>");
    }
    ASSIGN_OR_RETURN(std::vector<Value> values,
                     ParseValues(base::make_span(args).subspan(2)));
    return AddToAttributeCommand(args[1], std::move(values));
  } else if (args[0] == "delete") {
    if (args.size() != 1) {
      return Err(Location(), "Invalid delete command.", "Usage: delete");
    }
    return DeleteCommand();
  } else if (args[0] == "move") {
    if (args.size() < 4) {
      return Err(Location(), "Invalid move command.",
                 "Usage: move <from_attribute> <to_attribute> <value(s)>");
    }
    ASSIGN_OR_RETURN(std::vector<Value> values,
                     ParseValues(base::make_span(args).subspan(3)));
    return MoveCommand(args[1], args[2], std::move(values));
  } else if (args[0] == "new") {
    if (args.size() == 2) {
      return NewCommand(
          args[1], [](BuildFile& build_file) -> Result<TreeNode::NodeLocation> {
            auto* root = build_file.root()->AsBlockMut();
            return std::make_pair(std::ref(root->statements()),
                                  root->statements().end());
          });
    } else if (args.size() == 4 &&
               (args[2] == "before" || args[2] == "after")) {
      return NewCommand(
          args[1],
          [rel = args[3], after = args[2] == "after"](
              BuildFile& build_file) -> Result<TreeNode::NodeLocation> {
            auto target = build_file.find_target(rel);
            if (!target) {
              return Err(Location(), "Target \"" + rel + "\" not found in " +
                                         build_file.source_file().value() +
                                         ".");
            }
            auto [container, it] = target->node.node_location();
            if (after)
              it++;
            return std::make_pair(std::ref(container), it);
          });
    } else {
      return Err(Location(), "Invalid new command.",
                 "Usage: new <rule_kind> [(before|after) "
                 "<relative_rule_name>]");
    }
  } else if (args[0] == "remove") {
    if (args.size() < 2) {
      return Err(Location(), "Invalid remove command.",
                 "Usage: remove <attribute> [<value(s)>]");
    } else if (args.size() == 2) {
      return RemoveAttributeCommand(args[1]);
    }
    ASSIGN_OR_RETURN(std::vector<Value> values,
                     ParseValues(base::make_span(args).subspan(2)));
    return RemoveFromAttributeCommand(args[1], std::move(values));
  } else if (args[0] == "rename") {
    if (args.size() != 3) {
      return Err(Location(), "Invalid rename command.",
                 "Usage: rename <from_attribute> <to_attribute>");
    }
    return RenameAttributeCommand(args[1], args[2]);
  } else if (args[0] == "set") {
    if (args.size() < 3) {
      return Err(Location(),
                 "Invalid set command: missing attribute or value.\n"
                 "Usage: set <attribute> <value...>");
    }

    std::string_view attribute = args[1];
    bool force_list = false;
    constexpr std::string_view kListSuffix = ":list";
    if (attribute.ends_with(kListSuffix)) {
      attribute.remove_suffix(kListSuffix.size());
      force_list = true;
    }

    auto value_args = base::make_span(args).subspan(2);
    Value val;
    if (value_args.size() > 1 || force_list) {
      ASSIGN_OR_RETURN(std::vector<Value> list_elements,
                       ParseValues(value_args));
      val = Value(nullptr, std::move(list_elements));
    } else {
      ASSIGN_OR_RETURN(val, ParseValue(value_args[0]));
    }

    return SetCommand(std::string(attribute), std::move(val));
  } else if (args[0] == "shard") {
    if (args.size() == 1) {
      return ShardCommand();
    } else if (args.size() == 2) {
      return ShardCommand(args[1]);
    } else if (args.size() == 3) {
      return ShardCommand(args[1], args[2]);
    } else {
      return Err(Location(), "Invalid shard command.",
                 "Usage: shard [sharded target type] [group type]");
    }
  } else {
    return Err(Location(),
               "Unknown edit command: " + std::string(args[0]) +
                   "\n"
                   "See `gn help edit` for list of supported commands.");
  }
}
