// 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/dart/element/type_provider.dart';
import 'package:analyzer/source/line_info.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/generated/element_type_provider.dart';
import 'package:nnbd_migration/src/decorated_type.dart';
import 'package:nnbd_migration/src/edge_origin.dart';
import 'package:nnbd_migration/src/nullability_node.dart';
import 'package:nnbd_migration/src/nullability_node_target.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;

  final LineInfo Function(String) _getLineInfo;

  AlreadyMigratedCodeDecorator(
      this._graph, this._typeProvider, this._getLineInfo);

  /// Transforms [type], which should have come from code that has already been
  /// migrated to NNBD, into the corresponding [DecoratedType].
  ///
  /// TODO(paulberry): do we still need element or can we use target now?
  DecoratedType decorate(
      DartType type, Element element, NullabilityNodeTarget target) {
    if (type.isVoid || type.isDynamic) {
      var node = NullabilityNode.forAlreadyMigrated(target);
      _graph.makeNullableUnion(
          node, AlwaysNullableTypeOrigin.forElement(element, type.isVoid));
      return DecoratedType(type, node);
    }
    NullabilityNode node;
    var nullabilitySuffix = type.nullabilitySuffix;
    if (nullabilitySuffix == NullabilitySuffix.question) {
      node = NullabilityNode.forAlreadyMigrated(target);
      _graph.makeNullableUnion(
          node, AlreadyMigratedTypeOrigin.forElement(element, true));
    } else {
      node = NullabilityNode.forAlreadyMigrated(target);
      _graph.makeNonNullableUnion(
          node, AlreadyMigratedTypeOrigin.forElement(element, false));
    }
    if (type is FunctionType) {
      for (var element in type.typeFormals) {
        DecoratedTypeParameterBounds.current.put(
            element,
            decorate(
                element.bound ??
                    (_typeProvider.objectType as TypeImpl)
                        .withNullability(NullabilitySuffix.question),
                element,
                target.typeFormalBound(element.name)));
      }
      var positionalParameters = <DecoratedType>[];
      var namedParameters = <String, DecoratedType>{};
      int index = 0;
      for (var parameter in type.parameters) {
        if (parameter.isPositional) {
          positionalParameters.add(decorate(
              parameter.type, element, target.positionalParameter(index++)));
        } else {
          var name = parameter.name;
          namedParameters[name] =
              decorate(parameter.type, element, target.namedParameter(name));
        }
      }
      return DecoratedType(type, node,
          returnType: decorate(type.returnType, element, target.returnType()),
          namedParameters: namedParameters,
          positionalParameters: positionalParameters);
    } else if (type is InterfaceType) {
      var typeParameters = type.element.typeParameters;
      if (typeParameters.isNotEmpty) {
        assert(type.typeArguments.length == typeParameters.length);
        int index = 0;
        return DecoratedType(type, node, typeArguments: [
          for (var t in type.typeArguments)
            decorate(t, element, target.typeArgument(index++))
        ]);
      }
      return DecoratedType(type, node);
    } else if (type is TypeParameterType) {
      return DecoratedType(type, node);
    } else if (type.isBottom) {
      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_.preMigrationInterfaces);
    allSupertypes.addAll(class_.mixins);
    var type = class_.thisType;
    if (type.isDartAsyncFuture) {
      // Add FutureOr<T> as a supertype of Future<T>.
      allSupertypes.add(_typeProvider.futureOrType(type.typeArguments.single));
    }
    return [
      for (var t in allSupertypes)
        decorate(t, class_, NullabilityNodeTarget.element(class_, _getLineInfo))
    ];
  }
}

extension on ClassElement {
  List<InterfaceType> get preMigrationInterfaces {
    var previousElementTypeProvider = ElementTypeProvider.current;
    try {
      ElementTypeProvider.current = const ElementTypeProvider();
      return interfaces;
    } finally {
      ElementTypeProvider.current = previousElementTypeProvider;
    }
  }
}
