// 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:nnbd_migration/src/decorated_type.dart';
import 'package:nnbd_migration/src/nullability_node.dart';
import 'package:nnbd_migration/src/variables.dart';

/// Responsible for building and maintaining information about nullability
/// decorations related to the class hierarchy.
///
/// For instance, if one class is a subclass of the other, we record the
/// nullabilities of all the types involved in the subclass relationship.
class DecoratedClassHierarchy {
  final Variables? _variables;

  final NullabilityGraph _graph;

  /// Cache for speeding up the computation of
  /// [_getGenericSupertypeDecorations].
  final Map<ClassElement, Map<ClassElement, DecoratedType>>
      _genericSupertypeDecorations = {};

  DecoratedClassHierarchy(this._variables, this._graph);

  /// Retrieves a [DecoratedType] describing how [type] implements [superclass].
  ///
  /// If the [type] is a [TypeParameterType], it will be resolved against its
  /// bound.
  DecoratedType asInstanceOf(DecoratedType type, ClassElement? superclass) {
    type = _getInterfaceType(type);
    var typeType = type.type as InterfaceType;
    var class_ = typeType.element;
    if (class_ == superclass) return type;
    var result = getDecoratedSupertype(class_, superclass!);
    if (result.typeArguments.isNotEmpty && type.typeArguments.isNotEmpty) {
      // TODO(paulberry): test
      result = result.substitute(type.asSubstitution);
    }
    return result.withNode(type.node);
  }

  /// Retrieves a [DecoratedType] describing how [class_] implements
  /// [superclass].
  ///
  /// If [class_] does not implement [superclass], raises an exception.
  ///
  /// Note that the returned [DecoratedType] will have a node of `never`,
  /// because the relationship between a class and its superclass is not
  /// nullable.
  DecoratedType getDecoratedSupertype(
      ClassElement class_, ClassElement superclass) {
    assert(!(class_.library.isDartCore && class_.name == 'Null'));
    if (superclass.typeParameters.isEmpty) {
      return DecoratedType(
        superclass.instantiate(
          typeArguments: const [],
          nullabilitySuffix: NullabilitySuffix.none,
        ),
        _graph.never,
      );
    }
    return _getGenericSupertypeDecorations(class_)[superclass] ??
        (throw StateError('Unrelated types: $class_ and $superclass'));
  }

  /// Computes a map whose keys are all the superclasses of [class_], and whose
  /// values indicate how [class_] implements each superclass.
  Map<ClassElement, DecoratedType> _getGenericSupertypeDecorations(
      ClassElement class_) {
    var decorations = _genericSupertypeDecorations[class_];
    if (decorations == null) {
      // Call ourselves recursively to compute how each of [class_]'s direct
      // superclasses relates to all of its transitive superclasses.
      decorations = {};
      var decoratedDirectSupertypes =
          _variables!.decoratedDirectSupertypes(class_);
      for (var entry in decoratedDirectSupertypes.entries) {
        var superclass = entry.key;
        var decoratedSupertype = entry.value!;
        var supertype = decoratedSupertype.type as InterfaceType;
        // Compute a type substitution to determine how [class_] relates to
        // this specific [superclass].
        Map<TypeParameterElement, DecoratedType?> substitution = {};
        for (int i = 0; i < supertype.typeArguments.length; i++) {
          substitution[supertype.element.typeParameters[i]] =
              decoratedSupertype.typeArguments[i];
        }
        // Apply that substitution to the relation between [superclass] and
        // each of its transitive superclasses, to determine the relation
        // between [class_] and the transitive superclass.
        var recursiveSupertypeDecorations =
            _getGenericSupertypeDecorations(superclass);
        for (var entry in recursiveSupertypeDecorations.entries) {
          decorations[entry.key] ??= entry.value.substitute(substitution);
        }
        // Also record the relation between [class_] and its direct
        // superclass.
        decorations[superclass] ??= decoratedSupertype;
      }
      _genericSupertypeDecorations[class_] = decorations;
    }
    return decorations;
  }

  DecoratedType _getInterfaceType(DecoratedType type) {
    var typeType = type.type;
    if (typeType is InterfaceType) {
      return type;
    }

    if (typeType is TypeParameterType) {
      final innerType = _getInterfaceType(
          _variables!.decoratedTypeParameterBound(typeType.element)!);
      return type.substitute({typeType.element: innerType});
    }

    throw ArgumentError('$type is an unexpected type');
  }
}
