// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/source/source_range.dart';

/// A selection within a compilation unit.
class Selection {
  /// The offset of the selection.
  final int offset;

  /// The length of the selection.
  final int length;

  /// The most deeply nested node whose range completely includes the selected
  /// range of characters.
  final AstNode coveringNode;

  /// Initialize a newly created selection to include the characters starting at
  /// the [offset] and including [length] characters, all of which fall within
  /// the [coveringNode].
  Selection({
    required this.offset,
    required this.length,
    required this.coveringNode,
  });

  bool isCoveredByNode(AstNode node) {
    return node.offset <= offset && offset + length <= node.end;
  }

  bool isCoveredByToken(Token token) {
    return token.offset <= offset && offset + length <= token.end;
  }

  /// Returns the contiguous subset of [coveringNode] children that are at
  /// least partially covered by the selection. Touching is not enough.
  ///
  /// A list of nodes is defined to be _contiguous_ if they are syntactically
  /// adjacent with no intervening tokens other than comments or commas. For
  /// example, the nodes might be a sequence of members in a compilation unit, a
  /// sequence of statements in a block, or a sequence of parameters in a
  /// parameter list that don't cross a separator such as `{` or `[`.
  List<AstNode> nodesInRange() {
    var rangeFinder = _ChildrenFinder(SourceRange(offset, length));
    coveringNode.accept(rangeFinder);
    return rangeFinder.nodes;
  }
}

/// A visitor used to find a sequence of nodes within the node being visited
/// that together cover the range.
class _ChildrenFinder extends SimpleAstVisitor<void> {
  /// The range that the sequence of nodes must cover.
  final SourceRange range;

  /// The nodes within the range.
  List<AstNode> nodes = [];

  /// Initialize a newly created visitor.
  _ChildrenFinder(this.range);

  @override
  void visitAdjacentStrings(AdjacentStrings node) {
    _fromList(node.strings);
  }

  @override
  void visitArgumentList(ArgumentList node) {
    _fromList(node.arguments);
  }

  @override
  void visitBlock(Block node) {
    _fromList(node.statements);
  }

  @override
  void visitBlockClassBody(BlockClassBody node) {
    _fromList(node.members);
  }

  @override
  void visitBlockEnumBody(BlockEnumBody node) {
    _fromList(node.constants) || _fromList(node.members);
  }

  @override
  void visitCascadeExpression(CascadeExpression node) {
    _fromList(node.cascadeSections);
  }

  @override
  void visitClassDeclaration(ClassDeclaration node) {
    _fromList(node.metadata);
  }

  @override
  void visitClassTypeAlias(ClassTypeAlias node) {
    _fromList(node.metadata);
  }

  @override
  void visitCompilationUnit(CompilationUnit node) {
    // TODO(brianwilkerson): Support selecting both directives and declarations.
    _fromList(node.directives) || _fromList(node.declarations);
  }

  @override
  void visitConstructorDeclaration(ConstructorDeclaration node) {
    _fromList(node.metadata) || _fromList(node.initializers);
  }

  @override
  void visitDeclaredIdentifier(DeclaredIdentifier node) {
    _fromList(node.metadata);
  }

  @override
  void visitEnumConstantDeclaration(EnumConstantDeclaration node) {
    _fromList(node.metadata);
  }

  @override
  void visitEnumDeclaration(EnumDeclaration node) {
    _fromList(node.metadata);
  }

  @override
  void visitExportDirective(ExportDirective node) {
    _fromList(node.metadata) ||
        _fromList(node.configurations) ||
        _fromList(node.combinators);
  }

  @override
  void visitExtensionDeclaration(ExtensionDeclaration node) {
    _fromList(node.metadata);
  }

  @override
  void visitExtensionTypeDeclaration(ExtensionTypeDeclaration node) {
    _fromList(node.metadata);
  }

  @override
  void visitFieldDeclaration(FieldDeclaration node) {
    _fromList(node.metadata);
  }

  @override
  void visitFieldFormalParameter(FieldFormalParameter node) {
    _fromList(node.metadata);
  }

  @override
  void visitForEachPartsWithPattern(ForEachPartsWithPattern node) {
    _fromList(node.metadata);
  }

  @override
  void visitFormalParameterList(FormalParameterList node) {
    var delimiter = node.leftDelimiter;
    if (delimiter == null || !range.contains(delimiter.offset)) {
      _fromList(node.parameters);
    }
  }

  @override
  void visitForPartsWithDeclarations(ForPartsWithDeclarations node) {
    _fromList(node.updaters);
  }

  @override
  void visitForPartsWithExpression(ForPartsWithExpression node) {
    _fromList(node.updaters);
  }

  @override
  void visitForPartsWithPattern(ForPartsWithPattern node) {
    _fromList(node.updaters);
  }

  @override
  void visitFunctionDeclaration(FunctionDeclaration node) {
    _fromList(node.metadata);
  }

  @override
  void visitFunctionTypeAlias(FunctionTypeAlias node) {
    _fromList(node.metadata);
  }

  @override
  void visitGenericTypeAlias(GenericTypeAlias node) {
    _fromList(node.metadata);
  }

  @override
  void visitHideCombinator(HideCombinator node) {
    _fromList(node.hiddenNames);
  }

  @override
  void visitImplementsClause(ImplementsClause node) {
    _fromList(node.interfaces);
  }

  @override
  void visitImportDirective(ImportDirective node) {
    _fromList(node.metadata) ||
        _fromList(node.configurations) ||
        _fromList(node.combinators);
  }

  @override
  void visitLabeledStatement(LabeledStatement node) {
    _fromList(node.labels);
  }

  @override
  void visitLibraryDirective(LibraryDirective node) {
    _fromList(node.metadata);
  }

  @override
  void visitListLiteral(ListLiteral node) {
    _fromList(node.elements);
  }

  @override
  void visitListPattern(ListPattern node) {
    _fromList(node.elements);
  }

  @override
  void visitMapPattern(MapPattern node) {
    _fromList(node.elements);
  }

  @override
  void visitMethodDeclaration(MethodDeclaration node) {
    _fromList(node.metadata);
  }

  @override
  void visitMixinDeclaration(MixinDeclaration node) {
    _fromList(node.metadata);
  }

  @override
  void visitMixinOnClause(MixinOnClause node) {
    _fromList(node.superclassConstraints);
  }

  @override
  void visitObjectPattern(ObjectPattern node) {
    _fromList(node.fields);
  }

  @override
  void visitPartDirective(PartDirective node) {
    _fromList(node.metadata);
  }

  @override
  void visitPartOfDirective(PartOfDirective node) {
    _fromList(node.metadata);
  }

  @override
  void visitPatternVariableDeclaration(PatternVariableDeclaration node) {
    _fromList(node.metadata);
  }

  @override
  void visitRecordLiteral(RecordLiteral node) {
    _fromList(node.fields);
  }

  @override
  void visitRecordPattern(RecordPattern node) {
    _fromList(node.fields);
  }

  @override
  void visitRecordTypeAnnotation(RecordTypeAnnotation node) {
    _fromList(node.positionalFields);
  }

  @override
  void visitRecordTypeAnnotationNamedField(
    RecordTypeAnnotationNamedField node,
  ) {
    _fromList(node.metadata);
  }

  @override
  void visitRecordTypeAnnotationNamedFields(
    RecordTypeAnnotationNamedFields node,
  ) {
    _fromList(node.fields);
  }

  @override
  void visitRecordTypeAnnotationPositionalField(
    RecordTypeAnnotationPositionalField node,
  ) {
    _fromList(node.metadata);
  }

  @override
  void visitSetOrMapLiteral(SetOrMapLiteral node) {
    _fromList(node.elements);
  }

  @override
  void visitShowCombinator(ShowCombinator node) {
    _fromList(node.shownNames);
  }

  @override
  void visitRegularFormalParameter(RegularFormalParameter node) {
    _fromList(node.metadata);
  }

  @override
  void visitStringInterpolation(StringInterpolation node) {
    _fromList(node.elements);
  }

  @override
  void visitSuperFormalParameter(SuperFormalParameter node) {
    _fromList(node.metadata);
  }

  @override
  void visitSwitchCase(SwitchCase node) {
    _fromList(node.labels) || _fromList(node.statements);
  }

  @override
  void visitSwitchDefault(SwitchDefault node) {
    _fromList(node.labels) || _fromList(node.statements);
  }

  @override
  void visitSwitchExpression(SwitchExpression node) {
    _fromList(node.cases);
  }

  @override
  void visitSwitchPatternCase(SwitchPatternCase node) {
    _fromList(node.labels) || _fromList(node.statements);
  }

  @override
  void visitSwitchStatement(SwitchStatement node) {
    _fromList(node.members);
  }

  @override
  void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
    _fromList(node.metadata);
  }

  @override
  void visitTryStatement(TryStatement node) {
    _fromList(node.catchClauses);
  }

  @override
  void visitTypeArgumentList(TypeArgumentList node) {
    _fromList(node.arguments);
  }

  @override
  void visitTypeParameter(TypeParameter node) {
    _fromList(node.metadata);
  }

  @override
  void visitTypeParameterList(TypeParameterList node) {
    _fromList(node.typeParameters);
  }

  @override
  void visitVariableDeclarationList(VariableDeclarationList node) {
    _fromList(node.metadata) || _fromList(node.variables);
  }

  @override
  void visitWithClause(WithClause node) {
    _fromList(node.mixinTypes);
  }

  /// If one or more of the [elements] in the list can cover the [range], then
  /// add the elements to the list of [nodes] and return `true`.
  bool _fromList(List<AstNode> elements) {
    var first = elements.length;
    for (; first > 0; first--) {
      var element = elements[first - 1];
      if (element.end <= range.offset) {
        break;
      }
    }

    var last = first;
    for (; last < elements.length; last++) {
      var element = elements[last];
      if (element.offset >= range.end) {
        break;
      }
      nodes.add(element);
    }

    return nodes.isNotEmpty;
  }
}

extension CompilationUnitExtension on CompilationUnit {
  /// Return the selection that includes the characters starting at the [offset]
  /// with the given [length].
  Selection? select({required int offset, required int length}) {
    var coveringNode = nodeCovering(offset: offset, length: length);
    if (coveringNode == null) {
      return null;
    }
    return Selection(
      offset: offset,
      length: length,
      coveringNode: coveringNode,
    );
  }
}
