// Copyright (c) 2017, 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 '../common_elements.dart';
import '../elements/entities.dart';
import '../elements/types.dart';
import '../ordered_typeset.dart';
import 'element_map.dart';

/// Support for subtype checks of kernel based [DartType]s.
class KernelDartTypes extends DartTypes {
  final IrToElementMap elementMap;
  final SubtypeVisitor<DartType> subtypeVisitor;
  final PotentialSubtypeVisitor<DartType> potentialSubtypeVisitor;

  KernelDartTypes(this.elementMap)
      : this.subtypeVisitor = new KernelSubtypeVisitor(elementMap),
        this.potentialSubtypeVisitor =
            new _KernelPotentialSubtypeVisitor(elementMap);

  @override
  bool isPotentialSubtype(DartType t, DartType s,
      {bool assumeInstantiations: true}) {
    return potentialSubtypeVisitor.isPotentialSubtype(t, s,
        assumeInstantiations: assumeInstantiations);
  }

  @override
  bool isAssignable(DartType t, DartType s) {
    return isSubtype(t, s) || isSubtype(s, t);
  }

  @override
  bool isSubtype(DartType t, DartType s) {
    return subtypeVisitor.isSubtype(t, s);
  }

  @override
  InterfaceType getThisType(ClassEntity cls) {
    return elementMap.getThisType(cls);
  }

  @override
  InterfaceType getSupertype(ClassEntity cls) {
    return elementMap.getSuperType(cls);
  }

  @override
  Iterable<InterfaceType> getSupertypes(ClassEntity cls) {
    return elementMap.getOrderedTypeSet(cls).supertypes;
  }

  @override
  Iterable<InterfaceType> getInterfaces(ClassEntity cls) {
    return elementMap.getInterfaces(cls);
  }

  @override
  InterfaceType asInstanceOf(InterfaceType type, ClassEntity cls) {
    return elementMap.asInstanceOf(type, cls);
  }

  @override
  DartType substByContext(DartType base, InterfaceType context) {
    return elementMap.substByContext(base, context);
  }

  @override
  FunctionType getCallType(InterfaceType type) {
    DartType callType = elementMap.getCallType(type);
    return callType is FunctionType ? callType : null;
  }

  @override
  void checkTypeVariableBounds<T>(
      T context,
      List<DartType> typeArguments,
      List<DartType> typeVariables,
      void checkTypeVariableBound(T context, DartType typeArgument,
          TypeVariableType typeVariable, DartType bound)) {
    assert(typeVariables.length == typeArguments.length);
    for (int index = 0; index < typeArguments.length; index++) {
      DartType typeArgument = typeArguments[index];
      TypeVariableType typeVariable = typeVariables[index];
      DartType bound = elementMap
          .getTypeVariableBound(typeVariable.element)
          .subst(typeArguments, typeVariables);
      checkTypeVariableBound(context, typeArgument, typeVariable, bound);
    }
  }

  @override
  CommonElements get commonElements => elementMap.commonElements;
}

class KernelOrderedTypeSetBuilder extends OrderedTypeSetBuilderBase {
  final IrToElementMap elementMap;

  KernelOrderedTypeSetBuilder(this.elementMap, ClassEntity cls) : super(cls);

  @override
  InterfaceType getThisType(ClassEntity cls) {
    return elementMap.getThisType(cls);
  }

  @override
  InterfaceType substByContext(InterfaceType type, InterfaceType context) {
    return elementMap.substByContext(type, context);
  }

  @override
  int getHierarchyDepth(ClassEntity cls) {
    return elementMap.getHierarchyDepth(cls);
  }

  @override
  OrderedTypeSet getOrderedTypeSet(ClassEntity cls) {
    return elementMap.getOrderedTypeSet(cls);
  }
}

abstract class AbstractTypeRelationMixin
    implements AbstractTypeRelation<DartType> {
  IrToElementMap get elementMap;

  @override
  CommonElements get commonElements => elementMap.commonElements;

  @override
  DartType getTypeVariableBound(TypeVariableEntity element) {
    return elementMap.getTypeVariableBound(element);
  }

  @override
  FunctionType getCallType(InterfaceType type) {
    return elementMap.getCallType(type);
  }

  @override
  InterfaceType asInstanceOf(InterfaceType type, ClassEntity cls) {
    return elementMap.asInstanceOf(type, cls);
  }
}

class KernelSubtypeVisitor extends SubtypeVisitor<DartType>
    with AbstractTypeRelationMixin {
  @override
  final IrToElementMap elementMap;

  KernelSubtypeVisitor(this.elementMap);
}

class _KernelPotentialSubtypeVisitor extends PotentialSubtypeVisitor<DartType>
    with AbstractTypeRelationMixin {
  @override
  final IrToElementMap elementMap;

  _KernelPotentialSubtypeVisitor(this.elementMap);
}
