// Copyright (c) 2014, 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:analysis_server/src/protocol_server.dart';
import 'package:analysis_server/src/services/correction/status.dart';
import 'package:analysis_server/src/services/refactoring/naming_conventions.dart';
import 'package:analysis_server/src/services/refactoring/refactoring.dart';
import 'package:analysis_server/src/services/refactoring/refactoring_internal.dart';
import 'package:analysis_server/src/services/refactoring/rename.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/utilities/range_factory.dart';

/// A [Refactoring] for renaming [ImportElement]s.
class RenameImportRefactoringImpl extends RenameRefactoringImpl {
  final AnalysisSession session;

  RenameImportRefactoringImpl(
      RefactoringWorkspace workspace, this.session, ImportElement element)
      : super(workspace, element);

  @override
  ImportElement get element => super.element as ImportElement;

  @override
  String get refactoringName {
    return 'Rename Import Prefix';
  }

  @override
  Future<RefactoringStatus> checkFinalConditions() {
    var result = RefactoringStatus();
    return Future.value(result);
  }

  @override
  RefactoringStatus checkNewName() {
    var result = super.checkNewName();
    result.addStatus(validateImportPrefixName(newName));
    return result;
  }

  @override
  Future<void> fillChange() async {
    // update declaration
    {
      var prefix = element.prefix;
      SourceEdit? edit;
      if (newName.isEmpty) {
        // We should not get `prefix == null` because we check in
        // `checkNewName` that the new name is different.
        if (prefix == null) {
          return;
        }
        var node = await _findNode();
        if (node != null) {
          var uriEnd = node.uri.end;
          var prefixEnd = prefix.nameOffset + prefix.nameLength;
          edit = newSourceEdit_range(
              range.startOffsetEndOffset(uriEnd, prefixEnd), '');
        }
      } else {
        if (prefix == null) {
          var node = await _findNode();
          if (node != null) {
            var uriEnd = node.uri.end;
            edit = newSourceEdit_range(SourceRange(uriEnd, 0), ' as $newName');
          }
        } else {
          var offset = prefix.nameOffset;
          var length = prefix.nameLength;
          edit = newSourceEdit_range(SourceRange(offset, length), newName);
        }
      }
      if (edit != null) {
        doSourceChange_addElementEdit(change, element, edit);
      }
    }
    // update references
    var matches = await searchEngine.searchReferences(element);
    var references = getSourceReferences(matches);
    for (var reference in references) {
      if (newName.isEmpty) {
        reference.addEdit(change, '');
      } else {
        var identifier = await _getInterpolationIdentifier(reference);
        if (identifier != null) {
          doSourceChange_addElementEdit(
              change,
              reference.element,
              SourceEdit(identifier.offset, identifier.length,
                  '{$newName.${identifier.name}}'));
        } else {
          reference.addEdit(change, '$newName.');
        }
      }
    }
  }

  /// Return the [ImportDirective] node that corresponds to the [element].
  Future<ImportDirective?> _findNode() async {
    var library = element.library;
    var path = library.source.fullName;
    var unitResult = await session.getParsedUnit2(path);
    if (unitResult is! ParsedUnitResult) {
      return null;
    }
    var unit = unitResult.unit;
    var index = library.imports.indexOf(element);
    return unit.directives.whereType<ImportDirective>().elementAt(index);
  }

  /// If the given [reference] is before an interpolated [SimpleIdentifier] in
  /// an [InterpolationExpression] without surrounding curly brackets, return
  /// it. Otherwise return `null`.
  Future<SimpleIdentifier?> _getInterpolationIdentifier(
    SourceReference reference,
  ) async {
    var source = reference.element.source!;
    var unitResult = await session.getParsedUnit2(source.fullName);
    if (unitResult is! ParsedUnitResult) {
      return null;
    }
    var unit = unitResult.unit;
    var nodeLocator = NodeLocator(reference.range.offset);
    var node = nodeLocator.searchWithin(unit);
    if (node is SimpleIdentifier) {
      var parent = node.parent;
      if (parent is InterpolationExpression && parent.rightBracket == null) {
        return node;
      }
    }
    return null;
  }
}
