// 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/edge_builder.dart';
import 'package:nnbd_migration/src/expression_checks.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 NullabilityGraph _graph;

  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(NullabilityMigrationListener listener,
      {bool permissive: false})
      : this._(listener, NullabilityGraph(), permissive);

  NullabilityMigrationImpl._(this.listener, this._graph, this._permissive)
      : _variables = Variables(_graph);

  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(EdgeBuilder(result.typeProvider, result.typeSystem, _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;
}
