// 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/type.dart';
import 'package:nnbd_migration/src/decorated_type.dart';
import 'package:nnbd_migration/src/node_builder.dart';
import 'package:nnbd_migration/src/nullability_node.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 VariableRepository _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 [type] is not an interface type, or it does not implement [superclass],
  /// raises an exception.
  DecoratedType asInstanceOf(DecoratedType type, ClassElement superclass) {
    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.type, _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.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;
  }
}
