// 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 'dart:collection';

import 'package:analysis_server/src/protocol_server.dart' hide Element;
import 'package:analysis_server/src/services/correction/status.dart';
import 'package:analysis_server/src/services/refactoring/refactoring.dart';
import 'package:analysis_server/src/services/search/search_engine.dart';
import 'package:analysis_server/src/utilities/progress.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/generated/source.dart';

/// Return a new [SourceReference] instance for the given [match].
SourceReference getSourceReference(SearchMatch match) {
  return SourceReference(match);
}

/// When a [Source] (a file) is used in more than one context, [SearchEngine]
/// will return separate [SearchMatch]s for each context. But in rename
/// refactorings we want to update each [Source] only once.
List<SourceReference> getSourceReferences(List<SearchMatch> matches) {
  var uniqueReferences = HashMap<SourceReference, SourceReference>();
  for (var match in matches) {
    var newReference = getSourceReference(match);
    var oldReference = uniqueReferences[newReference];
    if (oldReference == null) {
      uniqueReferences[newReference] = newReference;
      oldReference = newReference;
    }
  }
  return uniqueReferences.keys.toList();
}

/// Abstract implementation of [Refactoring].
abstract class RefactoringImpl implements Refactoring {
  @override
  final List<String> potentialEditIds = <String>[];

  CancellationToken? cancellationToken;

  bool get isCancellationRequested =>
      cancellationToken?.isCancellationRequested ?? false;

  @override
  Future<RefactoringStatus> checkAllConditions() async {
    var result = RefactoringStatus();
    result.addStatus(await checkInitialConditions());
    if (result.hasFatalError) {
      return result;
    }
    result.addStatus(await checkFinalConditions());
    return result;
  }
}

/// The [SourceRange] in some [Source].
///
/// TODO(scheglov) inline this class as SearchMatch
class SourceReference {
  final SearchMatch _match;

  SourceReference(this._match);

  Element get element => _match.element;

  /// The full path of the file containing the match.
  String get file => _match.file;

  @override
  int get hashCode {
    var hash = file.hashCode;
    hash = ((hash << 16) & 0xFFFFFFFF) + range.hashCode;
    return hash;
  }

  bool get isConstructorTearOff =>
      _match.kind == MatchKind.REFERENCE_BY_CONSTRUCTOR_TEAR_OFF;

  bool get isInvocationByEnumConstantWithoutArguments =>
      _match.kind == MatchKind.INVOCATION_BY_ENUM_CONSTANT_WITHOUT_ARGUMENTS;

  bool get isResolved => _match.isResolved;

  SourceRange get range => _match.sourceRange;

  Source get unitSource => _match.unitSource;

  @override
  bool operator ==(Object other) {
    if (identical(other, this)) {
      return true;
    }
    if (other is SourceReference) {
      return other.file == file && other.range == range;
    }
    return false;
  }

  /// Adds the [SourceEdit] to replace this reference.
  void addEdit(SourceChange change, String newText, {String? id}) {
    var edit = createEdit(newText, id: id);
    doSourceChange_addSourceEdit(change, unitSource, edit);
  }

  /// Returns the [SourceEdit] to replace this reference.
  SourceEdit createEdit(String newText, {String? id}) {
    return newSourceEdit_range(range, newText, id: id);
  }

  @override
  String toString() => '$file@$range';
}
