// 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 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/dart/analysis/session.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type_system.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/nnbd_migration.dart';
import 'package:nnbd_migration/src/decorated_class_hierarchy.dart';
import 'package:nnbd_migration/src/decorated_type.dart';
import 'package:nnbd_migration/src/edge_builder.dart';
import 'package:nnbd_migration/src/edit_plan.dart';
import 'package:nnbd_migration/src/exceptions.dart';
import 'package:nnbd_migration/src/fix_aggregator.dart';
import 'package:nnbd_migration/src/fix_builder.dart';
import 'package:nnbd_migration/src/node_builder.dart';
import 'package:nnbd_migration/src/nullability_node.dart';
import 'package:nnbd_migration/src/variables.dart';
import 'package:pub_semver/pub_semver.dart';

/// Implementation of the [NullabilityMigration] public API.
class NullabilityMigrationImpl implements NullabilityMigration {
  final NullabilityMigrationListener? listener;

  Variables? _variables;

  final NullabilityGraph _graph;

  final bool? _permissive;

  final NullabilityMigrationInstrumentation? _instrumentation;

  DecoratedClassHierarchy? _decoratedClassHierarchy;

  bool _propagated = false;

  /// Indicates whether code removed by the migration engine should be removed
  /// by commenting it out.  A value of `false` means to actually delete the
  /// code that is removed.
  final bool? removeViaComments;

  final bool? warnOnWeakCode;

  final _decoratedTypeParameterBounds = DecoratedTypeParameterBounds();

  /// Map from [Source] object to a boolean indicating whether the source is
  /// opted in to null safety.
  final Map<Source, bool> _libraryOptInStatus = {};

  /// Indicates whether the client has used the [unmigratedDependencies] getter.
  bool _queriedUnmigratedDependencies = false;

  /// Map of additional package dependencies that will be required by the
  /// migrated code.  Keys are package names; values indicate the minimum
  /// required version of each package.
  final Map<String, Version> _neededPackages = {};

  /// 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]).
  NullabilityMigrationImpl(NullabilityMigrationListener? listener,
      {bool? permissive = false,
      NullabilityMigrationInstrumentation? instrumentation,
      bool? removeViaComments = false,
      bool? warnOnWeakCode = true})
      : this._(
          listener,
          NullabilityGraph(instrumentation: instrumentation),
          permissive,
          instrumentation,
          removeViaComments,
          warnOnWeakCode,
        );

  NullabilityMigrationImpl._(
    this.listener,
    this._graph,
    this._permissive,
    this._instrumentation,
    this.removeViaComments,
    this.warnOnWeakCode,
  ) {
    _instrumentation?.immutableNodes(_graph.never, _graph.always);
  }

  @override
  bool? get isPermissive => _permissive;

  @override
  List<String> get unmigratedDependencies {
    _queriedUnmigratedDependencies = true;
    var unmigratedDependencies = <Source>[];
    for (var entry in _libraryOptInStatus.entries) {
      if (_graph.isPathBeingMigrated(entry.key.fullName)) continue;
      if (!entry.value) {
        unmigratedDependencies.add(entry.key);
      }
    }
    var badUris = {
      for (var dependency in unmigratedDependencies) dependency.uri.toString()
    }.toList();
    badUris.sort();
    return badUris;
  }

  @override
  void finalizeInput(ResolvedUnitResult result) {
    if (result.unit.featureSet.isEnabled(Feature.non_nullable)) {
      // This library has already been migrated; nothing more to do.
      return;
    }
    ExperimentStatusException.sanityCheck(result);
    if (!_propagated) {
      _propagated = true;
      _graph.propagate();
    }
    var unit = result.unit;
    var compilationUnit = unit.declaredElement!;
    var library = compilationUnit.library;
    var source = compilationUnit.source;
    // Hierarchies were created assuming the libraries being migrated are opted
    // out, but the FixBuilder will analyze assuming they're opted in.  So we
    // need to clear the hierarchies before we continue.
    (result.session as AnalysisSessionImpl).clearHierarchies();
    var fixBuilder = FixBuilder(
        source,
        _decoratedClassHierarchy,
        result.typeProvider,
        library.typeSystem as TypeSystemImpl,
        _variables,
        library as LibraryElementImpl,
        _permissive! ? listener : null,
        unit,
        warnOnWeakCode,
        _graph,
        _neededPackages);
    try {
      DecoratedTypeParameterBounds.current = _decoratedTypeParameterBounds;
      fixBuilder.visitAll();
    } finally {
      DecoratedTypeParameterBounds.current = null;
    }
    var changes = FixAggregator.run(unit, result.content, fixBuilder.changes,
        removeViaComments: removeViaComments, warnOnWeakCode: warnOnWeakCode)!;
    _instrumentation?.changes(source, changes);
    final lineInfo = LineInfo.fromContent(source.contents.data);
    var offsets = changes.keys.toList();
    offsets.sort();
    for (var offset in offsets) {
      var edits = changes[offset]!;
      var descriptions = edits
          .map((edit) => edit.info)
          .where((info) => info != null)
          .map((info) => info!.description.appliedMessage)
          .join(', ');
      var sourceEdit = edits.toSourceEdit(offset!);
      listener!.addSuggestion(
          descriptions, _computeLocation(lineInfo, sourceEdit, source));
      listener!.addEdit(source, sourceEdit);
    }
  }

  Map<String, Version> finish() {
    _instrumentation?.finished();
    return _neededPackages;
  }

  void prepareInput(ResolvedUnitResult result) {
    assert(
        !_queriedUnmigratedDependencies,
        'Should only query unmigratedDependencies after all calls to '
        'prepareInput');
    if (result.unit.featureSet.isEnabled(Feature.non_nullable)) {
      // This library has already been migrated; nothing more to do.
      return;
    }
    ExperimentStatusException.sanityCheck(result);
    _recordTransitiveImportExportOptInStatus(
        result.libraryElement.importedLibraries);
    _recordTransitiveImportExportOptInStatus(
        result.libraryElement.exportedLibraries);
    if (_variables == null) {
      _variables = Variables(_graph, result.typeProvider,
          instrumentation: _instrumentation);
      _decoratedClassHierarchy = DecoratedClassHierarchy(_variables, _graph);
    }
    var unit = result.unit;
    try {
      DecoratedTypeParameterBounds.current = _decoratedTypeParameterBounds;
      unit.accept(NodeBuilder(_variables, unit.declaredElement!.source,
          _permissive! ? listener : null, _graph, result.typeProvider,
          instrumentation: _instrumentation));
    } finally {
      DecoratedTypeParameterBounds.current = null;
    }
  }

  void processInput(ResolvedUnitResult result) {
    if (result.unit.featureSet.isEnabled(Feature.non_nullable)) {
      // This library has already been migrated; nothing more to do.
      return;
    }
    ExperimentStatusException.sanityCheck(result);
    var unit = result.unit;
    try {
      DecoratedTypeParameterBounds.current = _decoratedTypeParameterBounds;
      unit.accept(EdgeBuilder(
          result.typeProvider,
          result.typeSystem,
          _variables,
          _graph,
          unit.declaredElement!.source,
          _permissive! ? listener : null,
          _decoratedClassHierarchy,
          result.libraryElement,
          instrumentation: _instrumentation));
    } finally {
      DecoratedTypeParameterBounds.current = null;
    }
  }

  @override
  void update() {
    _graph.update();
  }

  /// Records the opt in/out status of all libraries in [libraries], and any
  /// libraries they transitively import or export, in [_libraryOptInStatus].
  void _recordTransitiveImportExportOptInStatus(
      Iterable<LibraryElement> libraries) {
    var librariesToCheck = libraries.toList();
    while (librariesToCheck.isNotEmpty) {
      var library = librariesToCheck.removeLast();
      if (_libraryOptInStatus.containsKey(library.source)) continue;
      _libraryOptInStatus[library.source] = library.isNonNullableByDefault;
      librariesToCheck.addAll(library.importedLibraries);
      librariesToCheck.addAll(library.exportedLibraries);
    }
  }

  static Location _computeLocation(
      LineInfo lineInfo, SourceEdit edit, Source source) {
    final startLocation = lineInfo.getLocation(edit.offset);
    final endLocation = lineInfo.getLocation(edit.end);
    var location = Location(
      source.fullName,
      edit.offset,
      edit.length,
      startLocation.lineNumber,
      startLocation.columnNumber,
      endLine: endLocation.lineNumber,
      endColumn: endLocation.columnNumber,
    );
    return location;
  }
}
