// 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:analysis_server/src/protocol_server.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:nnbd_migration/nnbd_migration.dart';
import 'package:nnbd_migration/src/decorated_type.dart';
import 'package:nnbd_migration/src/expression_checks.dart';
import 'package:nnbd_migration/src/graph_builder.dart';
import 'package:nnbd_migration/src/node_builder.dart';
import 'package:nnbd_migration/src/nullability_node.dart';
import 'package:nnbd_migration/src/potential_modification.dart';
import 'package:nnbd_migration/src/variables.dart';

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

  final _variables = Variables();

  final _graph = NullabilityGraph();

  final bool _permissive;

  /// 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.
  NullabilityMigrationImpl(this.listener, {bool permissive: false})
      : _permissive = permissive;

  void finish() {
    _graph.propagate();
    for (var entry in _variables.getPotentialModifications().entries) {
      var source = entry.key;
      for (var potentialModification in entry.value) {
        var fix = _SingleNullabilityFix(source, potentialModification);
        listener.addFix(fix);
        for (var edit in potentialModification.modifications) {
          listener.addEdit(fix, edit);
        }
      }
    }
  }

  void prepareInput(ResolvedUnitResult result) {
    var unit = result.unit;
    unit.accept(NodeBuilder(_variables, unit.declaredElement.source,
        _permissive ? listener : null, _graph, result.typeProvider));
  }

  void processInput(ResolvedUnitResult result) {
    var unit = result.unit;
    unit.accept(GraphBuilder(result.typeProvider, _variables, _graph,
        unit.declaredElement.source, _permissive ? listener : null));
  }
}

/// Implementation of [SingleNullabilityFix] used internally by
/// [NullabilityMigration].
class _SingleNullabilityFix extends SingleNullabilityFix {
  @override
  final Source source;

  @override
  final NullabilityFixKind kind;

  factory _SingleNullabilityFix(
      Source source, PotentialModification potentialModification) {
    // TODO(paulberry): once everything is migrated into the analysis server,
    // the migration engine can just create SingleNullabilityFix objects
    // directly and set their kind appropriately; we won't need to translate the
    // kinds using a bunch of `is` checks.
    NullabilityFixKind kind;
    if (potentialModification is ExpressionChecks) {
      kind = NullabilityFixKind.checkExpression;
    } else if (potentialModification is DecoratedTypeAnnotation) {
      kind = NullabilityFixKind.makeTypeNullable;
    } else if (potentialModification is ConditionalModification) {
      kind = potentialModification.discard.keepFalse
          ? NullabilityFixKind.discardThen
          : NullabilityFixKind.discardElse;
    } else if (potentialModification is PotentiallyAddImport) {
      kind = NullabilityFixKind.addImport;
    } else if (potentialModification is PotentiallyAddRequired) {
      kind = NullabilityFixKind.addRequired;
    } else {
      throw new UnimplementedError('TODO(paulberry)');
    }
    return _SingleNullabilityFix._(source, kind);
  }

  _SingleNullabilityFix._(this.source, this.kind);

  /// TODO(paulberry): do something better
  Location get location => null;
}
