// 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 visitCascadeExpression(CascadeExpression node) {
    _fromList(node.cascadeSections);
  }

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

  @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 visitDefaultFormalParameter(DefaultFormalParameter node) {
    _fromList(node.metadata);
  }

  @override
  void visitDottedName(DottedName node) {
    _fromList(node.components);
  }

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

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

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

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

  @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 visitFunctionTypedFormalParameter(FunctionTypedFormalParameter 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 visitLibraryIdentifier(LibraryIdentifier node) {
    _fromList(node.components);
  }

  @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) || _fromList(node.members);
  }

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

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

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

  @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 visitSimpleFormalParameter(SimpleFormalParameter 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);
  }
}
