// Copyright (c) 2019, 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:convert';

import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:nnbd_migration/instrumentation.dart';
import 'package:nnbd_migration/src/nullability_migration_impl.dart';
import 'package:pub_semver/pub_semver.dart';

export 'package:nnbd_migration/src/utilities/hint_utils.dart' show HintComment;

/// Description of fixes that might be performed by nullability migration.
class NullabilityFixDescription {
  /// A `.then((value) => ...)` suffix was added to an expression.
  static const addThen = NullabilityFixDescription._(
      appliedMessage: 'Added `.then` to adjust type of Future expression',
      kind: NullabilityFixKind.addThen);

  /// An import was added to the library.
  static const addImport = NullabilityFixDescription._(
      appliedMessage: 'Added import for use in migrated code',
      kind: NullabilityFixKind.addImport);

  /// A variable declaration needs to be marked as "late".
  static const addLate = NullabilityFixDescription._(
      appliedMessage: 'Added a late keyword', kind: NullabilityFixKind.addLate);

  /// A variable declaration needs to be marked as "late" due to the presence of
  /// a `/*late*/` hint.
  static const addLateDueToHint = NullabilityFixDescription._(
      appliedMessage: 'Added a late keyword, due to a hint',
      kind: NullabilityFixKind.addLateDueToHint);

  /// A variable declaration needs to be marked as "late" due to being certainly
  /// assigned in test setup.
  static const addLateDueToTestSetup = NullabilityFixDescription._(
      appliedMessage: 'Added a late keyword, due to assignment in `setUp`',
      kind: NullabilityFixKind.addLateDueToTestSetup);

  /// A variable declaration needs to be marked as "late" and "final" due to the
  /// presence of a `/*late final*/` hint.
  static const addLateFinalDueToHint = NullabilityFixDescription._(
      appliedMessage: 'Added late and final keywords, due to a hint',
      kind: NullabilityFixKind.addLateFinalDueToHint);

  /// An expression's value needs to be null-checked.
  static const checkExpression = NullabilityFixDescription._(
    appliedMessage: 'Added a non-null assertion to nullable expression',
    kind: NullabilityFixKind.checkExpression,
  );

  /// An expression's value will be null-checked due to a hint.
  static const checkExpressionDueToHint = NullabilityFixDescription._(
    appliedMessage: 'Accepted a null check hint',
    kind: NullabilityFixKind.checkExpressionDueToHint,
  );

  /// A compound assignment's combiner operator returns a type that isn't
  /// assignable to the LHS of the assignment.
  static const compoundAssignmentHasBadCombinedType =
      NullabilityFixDescription._(
    appliedMessage: 'Compound assignment has bad combined type',
    kind: NullabilityFixKind.compoundAssignmentHasBadCombinedType,
  );

  /// A compound assignment's LHS has a nullable type.
  static const compoundAssignmentHasNullableSource =
      NullabilityFixDescription._(
    appliedMessage: 'Compound assignment has nullable source',
    kind: NullabilityFixKind.compoundAssignmentHasNullableSource,
  );

  /// Informative message: a condition of an if-test or conditional expression
  /// will always evaluate to `false` in strong checking mode.
  static const conditionFalseInStrongMode = NullabilityFixDescription._(
      appliedMessage: 'Condition will always be false in strong checking mode',
      kind: NullabilityFixKind.conditionFalseInStrongMode);

  /// Informative message: a condition of an if-test or conditional expression
  /// will always evaluate to `true` in strong checking mode.
  static const conditionTrueInStrongMode = NullabilityFixDescription._(
      appliedMessage: 'Condition will always be true in strong checking mode',
      kind: NullabilityFixKind.conditionTrueInStrongMode);

  /// An if-test or conditional expression needs to have its condition
  /// discarded.
  static const discardCondition = NullabilityFixDescription._(
    appliedMessage: 'Discarded a condition which is always true',
    kind: NullabilityFixKind.removeDeadCode,
  );

  /// An if-test or conditional expression needs to have its condition and
  /// "else" branch discarded.
  static const discardElse = NullabilityFixDescription._(
    appliedMessage: 'Discarded an unreachable conditional else branch',
    kind: NullabilityFixKind.removeDeadCode,
  );

  /// An if-test or conditional expression needs to have its condition and
  /// "then" branch discarded.
  static const discardThen = NullabilityFixDescription._(
    appliedMessage:
        'Discarded a condition which is always false, and the "then" branch '
        'that follows',
    kind: NullabilityFixKind.removeDeadCode,
  );

  /// An if-test needs to be discarded completely.
  static const discardIf = NullabilityFixDescription._(
    appliedMessage: 'Discarded an if-test with no effect',
    kind: NullabilityFixKind.removeDeadCode,
  );

  static const downcastExpression = NullabilityFixDescription._(
    appliedMessage: 'Added a downcast to an expression',
    kind: NullabilityFixKind.downcastExpression,
  );

  /// Informative message: there is no valid migration for `null` in a
  /// non-nullable context.
  static const noValidMigrationForNull = NullabilityFixDescription._(
      appliedMessage: 'No valid migration for expression with type `Null` in '
          'a non-nullable context',
      kind: NullabilityFixKind.noValidMigrationForNull);

  /// Informative message: a null-aware access won't be necessary in strong
  /// checking mode.
  static const nullAwarenessUnnecessaryInStrongMode =
      NullabilityFixDescription._(
          appliedMessage:
              'Null-aware access will be unnecessary in strong checking mode',
          kind: NullabilityFixKind.nullAwarenessUnnecessaryInStrongMode);

  /// Informative message: a null-aware assignment won't be necessary in strong
  /// checking mode.
  static const nullAwareAssignmentUnnecessaryInStrongMode =
      NullabilityFixDescription._(
          appliedMessage:
              'Null-aware assignment will be unnecessary in strong checking mode',
          kind: NullabilityFixKind.nullAwareAssignmentUnnecessaryInStrongMode);

  static const otherCastExpression = NullabilityFixDescription._(
    appliedMessage: 'Added a cast to an expression (non-downcast)',
    kind: NullabilityFixKind.otherCastExpression,
  );

  /// An unnecessary downcast has been discarded.
  static const removeLanguageVersionComment = NullabilityFixDescription._(
    appliedMessage: 'Removed language version comment so that null safety '
        'features will be allowed in this file',
    kind: NullabilityFixKind.removeLanguageVersionComment,
  );

  /// An unnecessary downcast has been discarded.
  static const removeAs = NullabilityFixDescription._(
    appliedMessage: 'Discarded a downcast that is now unnecessary',
    kind: NullabilityFixKind.removeAs,
  );

  /// A null-aware operator needs to be changed into its non-null-aware
  /// equivalent.
  static const removeNullAwareness = NullabilityFixDescription._(
      appliedMessage:
          'Changed a null-aware access into an ordinary access, because the target cannot be null',
      kind: NullabilityFixKind.removeDeadCode);

  /// A null-aware assignment was removed because its LHS is non-nullable.
  static const removeNullAwareAssignment = NullabilityFixDescription._(
      appliedMessage:
          'Removed a null-aware assignment, because the target cannot be null',
      kind: NullabilityFixKind.removeDeadCode);

  /// A built_value `@nullable` annotation has been discarded.
  static const removeNullableAnnotation = NullabilityFixDescription._(
    appliedMessage: 'Discarded a use of the built_value annotation @nullable',
    kind: NullabilityFixKind.removeNullableAnnotation,
  );

  /// A message used to indicate a fix has been applied.
  final String appliedMessage;

  /// The kind of fix described.
  final NullabilityFixKind kind;

  /// A formal parameter needs to have a required keyword added.
  factory NullabilityFixDescription.addRequired(
      String? className, String? functionName, String paramName) {
    var paramContainerName =
        className == null ? functionName! : "'$className.$functionName'";
    return NullabilityFixDescription._(
      appliedMessage: "Add 'required' keyword to parameter '$paramName' in "
          '$paramContainerName',
      kind: NullabilityFixKind.addRequired,
    );
  }

  /// An explicit type needs to be added.
  factory NullabilityFixDescription.addType(String typeText) =>
      NullabilityFixDescription._(
        appliedMessage: "Add the explicit type '$typeText'",
        kind: NullabilityFixKind.replaceVar,
      );

  /// A method call was changed from calling one method to another.
  factory NullabilityFixDescription.changeMethodName(
          String oldName, String newName) =>
      NullabilityFixDescription._(
          appliedMessage: "Changed method '$oldName' to '$newName'",
          kind: NullabilityFixKind.changeMethodName);

  /// An explicit type mentioned in the source program needs to be made
  /// nullable.
  factory NullabilityFixDescription.makeTypeNullable(String type) =>
      NullabilityFixDescription._(
        appliedMessage: "Changed type '$type' to be nullable",
        kind: NullabilityFixKind.makeTypeNullable,
      );

  /// An explicit type mentioned in the source program will be made
  /// nullable due to a nullability hint.
  factory NullabilityFixDescription.makeTypeNullableDueToHint(String type) =>
      NullabilityFixDescription._(
        appliedMessage:
            "Changed type '$type' to be nullable, due to a nullability hint",
        kind: NullabilityFixKind.makeTypeNullableDueToHint,
      );

  /// A 'var' declaration needs to be replaced with an explicit type.
  factory NullabilityFixDescription.replaceVar(String typeText) =>
      NullabilityFixDescription._(
        appliedMessage: "Replace 'var' with '$typeText'",
        kind: NullabilityFixKind.replaceVar,
      );

  /// An explicit type mentioned in the source program does not need to be made
  /// nullable.
  factory NullabilityFixDescription.typeNotMadeNullable(String type) =>
      NullabilityFixDescription._(
        appliedMessage: "Type '$type' was not made nullable",
        kind: NullabilityFixKind.typeNotMadeNullable,
      );

  /// An explicit type mentioned in the source program does not need to be made
  /// nullable.
  factory NullabilityFixDescription.typeNotMadeNullableDueToHint(String type) =>
      NullabilityFixDescription._(
        appliedMessage: "Type '$type' was not made nullable due to a hint",
        kind: NullabilityFixKind.typeNotMadeNullableDueToHint,
      );

  const NullabilityFixDescription._(
      {required this.appliedMessage, required this.kind});

  @override
  int get hashCode => Object.hash(appliedMessage, kind);

  @override
  bool operator ==(Object other) =>
      other is NullabilityFixDescription &&
      appliedMessage == other.appliedMessage &&
      kind == other.kind;

  @override
  String toString() =>
      'NullabilityFixDescription(${json.encode(appliedMessage)}, $kind)';
}

/// An enumeration of the various kinds of nullability fixes.
enum NullabilityFixKind {
  addThen,
  addImport,
  addLate,
  addLateDueToHint,
  addLateDueToTestSetup,
  addLateFinalDueToHint,
  addRequired,
  addType,
  changeMethodName,
  checkExpression,
  checkExpressionDueToHint,
  compoundAssignmentHasNullableSource,
  compoundAssignmentHasBadCombinedType,
  conditionFalseInStrongMode,
  conditionTrueInStrongMode,
  downcastExpression,
  makeTypeNullable,
  makeTypeNullableDueToHint,
  noValidMigrationForNull,
  nullAwarenessUnnecessaryInStrongMode,
  nullAwareAssignmentUnnecessaryInStrongMode,
  otherCastExpression,
  removeAs,
  removeDeadCode,
  removeLanguageVersionComment,
  removeNullableAnnotation,
  replaceVar,
  typeNotMadeNullable,
  typeNotMadeNullableDueToHint,
}

/// Provisional API for DartFix to perform nullability migration.
///
/// Usage: pass each input source file to [prepareInput].  Then pass each input
/// source file to [processInput].  Then pass each input source file to
/// [finalizeInput].  Then call [finish] to obtain the modifications that need
/// to be made to each source file.
abstract class NullabilityMigration {
  /// Prepares to perform nullability migration.
  ///
  /// If [permissive] is `true`, exception handling logic will try to proceed
  /// as far as possible even though the migration algorithm is not yet
  /// complete.  TODO(paulberry): remove this mode once the migration algorithm
  /// is fully implemented.
  ///
  /// Optional parameter [removeViaComments] indicates whether code that the
  /// migration tool wishes to remove should instead be commenting it out.
  ///
  /// Optional parameter [warnOnWeakCode] indicates whether weak-only code
  /// should be warned about or removed (in the way specified by
  /// [removeViaComments]).
  factory NullabilityMigration(NullabilityMigrationListener? listener,
      {bool? permissive,
      NullabilityMigrationInstrumentation? instrumentation,
      bool? removeViaComments,
      bool? warnOnWeakCode}) = NullabilityMigrationImpl;

  /// Check if this migration is being run permissively.
  bool? get isPermissive;

  /// Use this getter after any calls to [prepareInput] to obtain a list of URIs
  /// of unmigrated dependencies.  Ideally, this list should be empty before the
  /// user tries to migrate their package.
  List<String> get unmigratedDependencies;

  void finalizeInput(ResolvedUnitResult result);

  /// Finishes the migration.  Returns a map indicating packages that have been
  /// newly imported by the migration; the caller should ensure that these
  /// packages are properly imported by the package's pubspec.
  ///
  /// Keys of the returned map are package names; values indicate the minimum
  /// required version of each package.
  Map<String, Version> finish();

  void prepareInput(ResolvedUnitResult result);

  void processInput(ResolvedUnitResult result);

  /// Update the migration after an edge has been added or removed.
  void update();
}

/// [NullabilityMigrationListener] is used by [NullabilityMigration]
/// to communicate source changes or "fixes" to the client.
abstract class NullabilityMigrationListener {
  /// [addEdit] is called once for each source edit, in the order in which they
  /// appear in the source file.
  void addEdit(Source source, SourceEdit edit);

  void addSuggestion(String descriptions, Location location);

  /// [reportException] is called once for each exception that occurs in
  /// "permissive mode", reporting the location of the exception and the
  /// exception details.
  void reportException(
      Source? source, AstNode? node, Object exception, StackTrace stackTrace);
}
