// 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/element/element.dart';
import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/generated/resolver.dart';
import 'package:nnbd_migration/src/decorated_type.dart';
import 'package:nnbd_migration/src/nullability_node.dart';

/// This class transforms ordinary [DartType]s into their corresponding
/// [DecoratedType]s, assuming the [DartType]s come from code that has already
/// been migrated to NNBD.
class AlreadyMigratedCodeDecorator {
  final NullabilityGraph _graph;

  final TypeProvider _typeProvider;

  AlreadyMigratedCodeDecorator(this._graph, this._typeProvider);

  /// Transforms [type], which should have come from code that has already been
  /// migrated to NNBD, into the corresponding [DecoratedType].
  DecoratedType decorate(DartType type) {
    if (type.isVoid || type.isDynamic) {
      return DecoratedType(type, _graph.always);
    }
    NullabilityNode node;
    var nullabilitySuffix = (type as TypeImpl).nullabilitySuffix;
    if (nullabilitySuffix == NullabilitySuffix.question) {
      node = _graph.always;
    } else {
      // Currently, all types passed to this method have nullability suffix `star`
      // because (a) we don't yet have a migrated SDK, and (b) we haven't added
      // support to the migrator for analyzing packages that have already been
      // migrated with NNBD enabled.
      // TODO(paulberry): fix this assertion when things change.
      assert(nullabilitySuffix == NullabilitySuffix.star);
      node = _graph.never;
    }
    if (type is FunctionType) {
      var typeFormalBounds = type.typeFormals.map((e) {
        var bound = e.bound;
        if (bound == null) {
          return decorate((_typeProvider.objectType as TypeImpl)
              .withNullability(NullabilitySuffix.question));
        } else {
          return decorate(bound);
        }
      }).toList();
      var positionalParameters = <DecoratedType>[];
      var namedParameters = <String, DecoratedType>{};
      for (var parameter in type.parameters) {
        if (parameter.isPositional) {
          positionalParameters.add(decorate(parameter.type));
        } else {
          namedParameters[parameter.name] = decorate(parameter.type);
        }
      }
      return DecoratedType(type, node,
          typeFormalBounds: typeFormalBounds,
          returnType: decorate(type.returnType),
          namedParameters: namedParameters,
          positionalParameters: positionalParameters);
    } else if (type is InterfaceType) {
      if (type.typeParameters.isNotEmpty) {
        assert(type.typeArguments.length == type.typeParameters.length);
        return DecoratedType(type, node,
            typeArguments: type.typeArguments.map(decorate).toList());
      }
      return DecoratedType(type, node);
    } else if (type is TypeParameterType) {
      return DecoratedType(type, node);
    } else {
      // TODO(paulberry)
      throw UnimplementedError(
          'Unable to decorate already-migrated type $type');
    }
  }

  /// Get all the decorated immediate supertypes of the non-migrated class
  /// [class_].
  Iterable<DecoratedType> getImmediateSupertypes(ClassElement class_) {
    var allSupertypes = <DartType>[];
    var supertype = class_.supertype;
    if (supertype != null) {
      allSupertypes.add(supertype);
    }
    allSupertypes.addAll(class_.superclassConstraints);
    allSupertypes.addAll(class_.interfaces);
    allSupertypes.addAll(class_.mixins);
    var type = class_.thisType;
    if (type.isDartAsyncFuture) {
      // Add FutureOr<T> as a supertype of Future<T>.
      allSupertypes.add(_typeProvider.futureOrType2(type.typeArguments.single));
    }
    return allSupertypes.map(decorate);
  }
}
