// 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_command.h"

#include <iomanip>
#include <sstream>
#include <utility>
#include <vector>

#include "gn/build_file_editor.h"
#include "gn/commands.h"
#include "gn/edit_subcommands.h"
#include "gn/filesystem_utils.h"
#include "gn/setup.h"
#include "gn/source_file.h"
#include "gn/standard_out.h"
#include "gn/value.h"

namespace commands {

const char kEdit[] = "edit";
const char kEdit_HelpShort[] =
    "edit: Edit BUILD.gn files from the command line.";
const char kEdit_Help[] =
    "gn edit <command> <labels/patterns...>\n"
    "\n"
    "  Executes a command to modify a set of targets\n"
    "\n"
    "  Note: Because GN is an imperative language, it's not always entirely\n"
    "  clear what the \"correct\" thing is to do.\n"
    "\n"
    "  In cases of ambiguity (eg. conditionals), `gn edit` will leave notes\n"
    "  in your build files instructing you what to do.\n"
    "\n"
    "Commands:\n"
    "  add <attribute> <value(s)>\n"
    "      Adds <value(s)> to the list attribute <attribute>.\n"
    "      If the attribute does not exist, it is created.\n"
    "\n"
    "      Example:\n"
    "        gn edit \"add deps //base //src/tools:utils\" //src/tools:*\n"
    "\n"
    "  delete\n"
    "      Deletes the matched targets entirely.\n"
    "\n"
    "      Example:\n"
    "        gn edit \"delete\" //src/tools:old_target\n"
    "\n"
    "  move <from_attribute> <to_attribute> <value(s)>\n"
    "      Moves <value(s)> from the list <from_attribute> to <to_attribute>.\n"
    "      If <to_attribute> does not exist, it is created.\n"
    "\n"
    "      Example:\n"
    "        gn edit \"move deps public_deps //base\" //src/tools:*\n"
    "\n"
    "  new <rule_kind> [(before|after) <relative_rule_name>]\n"
    "      Adds a new rule at the end of the BUILD file (or before/after\n"
    "      <relative_rule_name>). The rule name is determined by the target "
    "label.\n"
    "\n"
    "      Examples:\n"
    "        gn edit \"new source_set\" //src/tools:my_target\n"
    "        gn edit \"new static_library before old_target\" "
    "//src/tools:helper\n"
    "\n"
    "  remove <attribute>\n"
    "      Removes <attribute> entirely.\n"
    "\n"
    "      Example:\n"
    "        gn edit \"remove testonly\" //src/tools:*\n"
    "\n"
    "  remove <attribute> <value(s)>\n"
    "      Removes <value(s)> from the list attribute <attribute>.\n"
    "\n"
    "      Example:\n"
    "        gn edit \"remove deps //base\" //src/tools:*\n"
    "\n"
    "  rename <from_attribute> <to_attribute>\n"
    "      Renames <from_attribute> to <to_attribute>.\n"
    "\n"
    "      Example:\n"
    "        gn edit \"rename srcs sources\" //src/tools:*\n"
    "\n"
    "  set <attribute>[:list] <value(s)>\n"
    "      Sets or overwrites the target's <attribute> to <value(s)>.\n"
    "      If multiple values are provided, or if the \":list\" suffix is\n"
    "      appended to the attribute, <value(s)> is interpreted as a list.\n"
    "\n"
    "      Examples:\n"
    "        gn edit \"set testonly true\" //src/tools:*\n"
    "        gn edit \"set srcs:list foo.cc\" //:foo\n"
    "        gn edit \"set deps :bar :baz\" //:foo\n";

Result<std::pair<std::vector<SourceFile>, EditState>> RunEditImpl(
    const std::vector<std::string>& args,
    Setup& setup) {
  if (args.size() < 2) {
    return Err(Location(), "Insufficient arguments.",
               "Usage: gn edit <command> <labels...>\n"
               "Example: gn edit \"set testonly true\" //foo:*");
  }

  // We use std::quoted to tokenize the command.
  // eg. set foo "bar baz" -> ["set", "foo", "bar baz"].
  std::stringstream ss(args[0]);
  std::vector<std::string> command_tokens;
  std::string token;
  while (ss >> std::ws && !ss.eof()) {
    if (!(ss >> std::quoted(token))) {
      return Err(Location(), "Unclosed quote in command string.");
    }
    command_tokens.push_back(std::move(token));
  }
  if (command_tokens.empty()) {
    return Err(Location(), "Empty command string.");
  }

  ASSIGN_OR_RETURN(EditCommand command,
                   ParseCommand(std::move(command_tokens)));
  const SourceDir current_dir =
      SourceDirForCurrentDirectory(setup.build_settings().root_path());
  const std::string source_root = setup.build_settings().root_path_utf8();

  std::vector<LabelPattern> patterns;
  for (size_t i = 1; i < args.size(); ++i) {
    Value val(nullptr, args[i]);
    Err err;
    LabelPattern pattern =
        LabelPattern::GetPattern(current_dir, source_root, val, &err);
    if (err.has_error()) {
      return err;
    }
    patterns.push_back(std::move(pattern));
  }

  ASSIGN_OR_RETURN(std::vector<BuildFile> build_files,
                   ::ResolvePatternsToBuildFiles(&setup.build_settings(),
                                                 setup.loader(), patterns));

  EditState state(args[0]);
  for (auto& build_file : build_files) {
    RETURN_IF_ERROR(command(build_file, state));
    RETURN_IF_ERROR(build_file.label_matcher().done());
  }

  std::vector<SourceFile> modified_files;
  for (auto& build_file : build_files) {
    ASSIGN_OR_RETURN(bool wrote, build_file.Write());
    if (wrote) {
      modified_files.push_back(build_file.source_file());
    }
  }

  return std::make_pair(std::move(modified_files), std::move(state));
}

int RunEdit(const std::vector<std::string>& args) {
  Setup setup;
  if (!setup.DoSetupForEditing()) {
    return 1;
  }
  auto result = RunEditImpl(args, setup);
  if (result.has_error()) {
    result.error().PrintToStdout();
    return 1;
  }
  for (const auto& file : result->first) {
    OutputString("Wrote '" + file.value() + "'.\n");
  }
  for (const auto& warning : result->second.warnings) {
    warning.PrintNonfatalToStdout();
  }
  const auto& review_needed = result->second.needs_manual_review;
  if (!review_needed.empty()) {
    OutputString("\nThe following targets need manual review:\n",
                 DECORATION_YELLOW);
    for (const Label& label : review_needed) {
      OutputString("* ");
      OutputString(label.GetUserVisibleName(false) + "\n", DECORATION_GREEN);
    }

    OutputString(
        "\nWhere manual review is required, comments have been added to the "
        "build file of the form:\n'# TODO(gn edit: <command>): ...'\n",
        DECORATION_DIM);
  }
  return 0;
}

}  // namespace commands
