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

#ifndef TOOLS_GN_BUILD_FILE_EDITOR_H_
#define TOOLS_GN_BUILD_FILE_EDITOR_H_

#include <functional>
#include <initializer_list>
#include <memory>
#include <optional>
#include <string_view>
#include <unordered_map>
#include <vector>

#include "gn/err.h"
#include "gn/input_file.h"
#include "gn/label.h"
#include "gn/label_pattern.h"
#include "gn/parse_tree.h"
#include "gn/source_file.h"

class BuildSettings;
class Loader;

struct EditState;
struct EditTarget;

// A TreeNode represents a node in a tree.
// It fundamentally represents a ParseNode, but differs from one as it
// understands where it exists in the tree.
class TreeNode {
 public:
  explicit TreeNode(std::vector<ParseNode*> stack) : stack_(std::move(stack)) {
    DCHECK(!stack_.empty());
  }

  ParseNode* node() const { return stack_.back(); }
  ParseNode* parent() const {
    return stack_.size() > 1 ? stack_[stack_.size() - 2] : nullptr;
  }

  // Returns the BinaryOpNode if the node is an assignment ("=" or "+=").
  BinaryOpNode* AsAssignment() const;

  // Returns whether the node is conditional in a target.
  // Note that if the target itself is conditional, this will return false.
  bool is_conditional() const;

  // Returns whether the node is a "+=" or "-=" operation.
  bool is_modification() const;

  // Adds a todo comment to the build file to show the user where manual
  // intervention is required.
  void add_todo(EditState& state,
                const EditTarget& target,
                std::string_view message) const;

  // Removes self from the tree, or adds a TODO suggesting that it should
  // probably be removed.
  void RemoveSelf(EditState& state, const EditTarget& target) const;

  using NodeList = std::vector<std::unique_ptr<ParseNode>>;
  using NodeListIterator = NodeList::iterator;
  using NodeLocation = std::pair<NodeList&, NodeListIterator>;

  // Returns the parent node's container (statements for BlockNode, contents for
  // ListNode).
  NodeList& container() const;

  // Returns the parent node's container and an iterator pointing to this node.
  NodeLocation node_location() const;

  // Removes self from the tree unconditionally without adding TODO comments.
  void RemoveSelfUnconditionally() const;

  ParseNode* operator->() const { return stack_.back(); }

  const std::vector<ParseNode*>& stack() const { return stack_; }

  TreeNode Descend(ParseNode* child) const;

  // Calculates all =, +=, and -= assignments of the given attributes under this
  // node.
  std::vector<TreeNode> assignments(
      std::initializer_list<std::string_view> attrs) const;
  std::vector<TreeNode> assignments(std::string_view attr) const;

 private:
  std::vector<ParseNode*> stack_;
};

template <typename T>
void FindStatementRecursive(
    ParseNode* node,
    std::vector<ParseNode*>& stack,
    const std::function<std::optional<T>(TreeNode&)>& transform,
    std::vector<T>* results) {
  if (!node)
    return;

  stack.push_back(node);

  TreeNode node_ref(stack);
  if (auto mapped = transform(node_ref)) {
    results->push_back(std::move(*mapped));
  }

  if (auto* block = node->AsBlockMut()) {
    for (const auto& stmt : block->statements()) {
      FindStatementRecursive(stmt.get(), stack, transform, results);
    }
  } else if (auto* condition = node->AsConditionMut()) {
    FindStatementRecursive(condition->if_true(), stack, transform, results);
    if (condition->if_false()) {
      FindStatementRecursive(condition->if_false(), stack, transform, results);
    }
  } else if (auto* func = node->AsFunctionCallMut(); func && func->block()) {
    FindStatementRecursive(func->block(), stack, transform, results);
  }

  stack.pop_back();
}

// Returns a vector of nodes matching a condition.
// May also apply a transformation to add useful metadata to them.
template <typename T>
std::vector<T> FindStatement(
    ParseNode* root,
    const std::function<std::optional<T>(TreeNode&)>& transform) {
  std::vector<T> results;
  std::vector<ParseNode*> stack;
  FindStatementRecursive<T>(root, stack, transform, &results);
  return results;
}

// Returns the string literal value if the node is a string literal.
std::optional<std::string> AsStringLiteral(const ParseNode* node);

// Finds all list elements directly in an assignment expression.
std::vector<TreeNode> FindAllListElements(const TreeNode& assignment);

// Finds an element in an assignment expression ("=" or "+=") whose right-hand
// side likely evaluates to a list.
std::vector<TreeNode> FindListElementInAssignment(const EditTarget& target,
                                                  const TreeNode& root,
                                                  const Value& value);

// Finds the first list node within an assignment expression.
std::optional<ListNode*> FindListInAssignment(const TreeNode& assignment);

// Represents a set of patterns within a build file.
class LabelMatcher {
 public:
  LabelMatcher(SourceDir source_dir, const std::vector<LabelPattern>& patterns);

  enum MatchType {
    // Target does not match any pattern in this build file.
    NONE,
    // Target was explicitly named (e.g. "//foo:bar"). Unmatched explicit
    // targets will trigger an error when done() is called.
    EXACT,
    // Target matched a wildcard pattern (e.g. "//foo:*" or "//foo/*").
    GLOB,
  };

  // Checks whether a label was a match for a given pattern.
  MatchType matches(const std::string& name);

  // Returns all explicitly named targets for this build file.
  Result<std::vector<std::string>> explicit_target_names();

  // Call this when done editing a build file.
  // Any explicitly requested targets that were unused will trigger an error.
  Err done() const;

 private:
  SourceDir source_dir_;
  bool globbed_ = false;
  std::vector<std::string> explicit_names_;
  std::unordered_map<std::string, bool> used_;
};

// Represents a build target to be edited.
struct EditTarget {
  // Calculates all =, +=, and -= of the given attributes.
  std::vector<TreeNode> assignments(
      std::initializer_list<std::string_view> attrs) const;
  std::vector<TreeNode> assignments(std::string_view attr) const;

  // Emits a warning to the user.
  void add_warning(EditState& state, std::string_view message) const;

  // True if the target was explicitly requested to be edited.
  // This is relevant, because if the user requests something like
  // "remove deps //dep" //:*, then we should not print warnings
  // if not all targets depend on //dep.
  // On the other hand, if the user says "remove deps //dep" //:foo,
  // and we can't find a dep on //dep, we should warn them about it.
  bool is_explicit;
  Label label;
  TreeNode node;
  BlockNode* block;
};

// Represents a build file to be edited.
class BuildFile {
 public:
  static Result<BuildFile> Create(const BuildSettings* build_settings,
                                  const SourceFile& source_file,
                                  const std::vector<LabelPattern>& patterns);

  const SourceFile& source_file() const { return source_file_; }
  ParseNode* root() const { return tree_root_.get(); }
  LabelMatcher& label_matcher() { return label_matcher_; }

  // Returns a generic location at the start of the file.
  // This is relevant because generated nodes won't have location information.
  Location location() const;

  // Returns all targets matching the patterns, or matching the given filter.
  std::vector<EditTarget> targets(
      std::function<bool(EditTarget&)> filter = nullptr);

  // Finds a target by name in the build file.
  // Returns std::nullopt if not found.
  std::optional<EditTarget> find_target(std::string_view target_name);

  // Creates a node to insert into the graph.
  std::unique_ptr<ParseNode> to_node(const Value& value);

  // Creates a node for an identifier.
  std::unique_ptr<IdentifierNode> create_identifier(std::string_view value);
  // Creates a node for `a = b`
  std::unique_ptr<BinaryOpNode> create_assignment(
      std::string_view name,
      std::unique_ptr<ParseNode> value);

  // Creates a BlockNode `{ ... }` with the given statements.
  std::unique_ptr<BlockNode> create_block(
      std::vector<std::unique_ptr<ParseNode>> statements = {});

  // Synthesizes a new target: `<type>("<name>") { ... }`
  std::unique_ptr<FunctionCallNode> create_target(
      std::string_view type,
      std::string_view name,
      std::unique_ptr<BlockNode> block);

  // Serializes the AST to the build file if it has changed.
  // Returns Ok(true) if the file was written, Ok(false) if it was unchanged.
  Result<bool> Write();

 private:
  BuildFile(const BuildSettings* build_settings,
            SourceFile source_file,
            std::unique_ptr<InputFile> input_file,
            std::unique_ptr<ParseNode> tree_root,
            LabelMatcher label_matcher);

  const BuildSettings* build_settings_;
  SourceFile source_file_;
  std::unique_ptr<InputFile> input_file_;
  std::unique_ptr<ParseNode> tree_root_;
  // Our custom ParseNodes generated by to_node contain string views.
  // We store objects containing the underlying strings here to ensure they
  // live long enough.
  std::vector<std::unique_ptr<InputFile>> extra_files_;
  LabelMatcher label_matcher_;
};

// Resolves a list of LabelPatterns into the union of the build files they
// cover.
Result<std::vector<BuildFile>> ResolvePatternsToBuildFiles(
    const BuildSettings* build_settings,
    const Loader* loader,
    const std::vector<LabelPattern>& patterns);

#endif  // TOOLS_GN_BUILD_FILE_EDITOR_H_
