// Copyright (c) 2013, 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.dart';
import '../common_elements.dart';
import '../elements/entities.dart';
import '../elements/types.dart';
import '../js/js.dart' as jsAst;
import '../js/js.dart' show js;
import '../ssa/codegen.dart' show SsaCodeGenerator;
import '../ssa/nodes.dart' show HTypeConversion;
import '../universe/call_structure.dart' show CallStructure;
import '../universe/use.dart' show StaticUse;
import 'namer.dart' show Namer;

class CheckedModeHelper {
  final String name;

  const CheckedModeHelper(String this.name);

  StaticUse getStaticUse(CommonElements commonElements) {
    // TODO(johnniwinther): Refactor this to avoid looking up directly in the
    // js helper library but instead access commonElements.
    return new StaticUse.staticInvoke(
        commonElements.findHelperFunction(name), callStructure);
  }

  CallStructure get callStructure => CallStructure.ONE_ARG;

  void generateAdditionalArguments(SsaCodeGenerator codegen, Namer namer,
      HTypeConversion node, List<jsAst.Expression> arguments) {
    // No additional arguments needed.
  }
}

class PropertyCheckedModeHelper extends CheckedModeHelper {
  const PropertyCheckedModeHelper(String name) : super(name);

  @override
  CallStructure get callStructure => CallStructure.TWO_ARGS;

  @override
  void generateAdditionalArguments(SsaCodeGenerator codegen, Namer namer,
      HTypeConversion node, List<jsAst.Expression> arguments) {
    DartType type = node.typeExpression;
    jsAst.Name additionalArgument = namer.operatorIsType(type);
    arguments.add(js.quoteName(additionalArgument));
  }
}

class TypeVariableCheckedModeHelper extends CheckedModeHelper {
  const TypeVariableCheckedModeHelper(String name) : super(name);

  @override
  CallStructure get callStructure => CallStructure.TWO_ARGS;

  @override
  void generateAdditionalArguments(SsaCodeGenerator codegen, Namer namer,
      HTypeConversion node, List<jsAst.Expression> arguments) {
    assert(node.typeExpression.isTypeVariable);
    codegen.use(node.typeRepresentation);
    arguments.add(codegen.pop());
  }
}

class FunctionTypeRepresentationCheckedModeHelper extends CheckedModeHelper {
  const FunctionTypeRepresentationCheckedModeHelper(String name) : super(name);

  @override
  CallStructure get callStructure => CallStructure.TWO_ARGS;

  @override
  void generateAdditionalArguments(SsaCodeGenerator codegen, Namer namer,
      HTypeConversion node, List<jsAst.Expression> arguments) {
    assert(node.typeExpression.isFunctionType);
    codegen.use(node.typeRepresentation);
    arguments.add(codegen.pop());
  }
}

class FutureOrRepresentationCheckedModeHelper extends CheckedModeHelper {
  const FutureOrRepresentationCheckedModeHelper(String name) : super(name);

  @override
  CallStructure get callStructure => CallStructure.TWO_ARGS;

  @override
  void generateAdditionalArguments(SsaCodeGenerator codegen, Namer namer,
      HTypeConversion node, List<jsAst.Expression> arguments) {
    assert(node.typeExpression.isFutureOr);
    codegen.use(node.typeRepresentation);
    arguments.add(codegen.pop());
  }
}

class SubtypeCheckedModeHelper extends CheckedModeHelper {
  const SubtypeCheckedModeHelper(String name) : super(name);

  @override
  CallStructure get callStructure => const CallStructure.unnamed(4);

  @override
  void generateAdditionalArguments(SsaCodeGenerator codegen, Namer namer,
      HTypeConversion node, List<jsAst.Expression> arguments) {
    // TODO(sra): Move these calls into the SSA graph so that the arguments can
    // be optimized, e,g, GVNed.
    InterfaceType type = node.typeExpression;
    ClassEntity element = type.element;
    jsAst.Name isField = namer.operatorIs(element);
    arguments.add(js.quoteName(isField));
    codegen.use(node.typeRepresentation);
    arguments.add(codegen.pop());
    jsAst.Name asField = namer.substitutionName(element);
    arguments.add(js.quoteName(asField));
  }
}

class CheckedModeHelpers {
  CheckedModeHelpers();

  /// All the checked mode helpers.
  static const List<CheckedModeHelper> helpers = const <CheckedModeHelper>[
    const CheckedModeHelper('stringTypeCast'),
    const CheckedModeHelper('stringTypeCheck'),
    const CheckedModeHelper('doubleTypeCast'),
    const CheckedModeHelper('doubleTypeCheck'),
    const CheckedModeHelper('numTypeCast'),
    const CheckedModeHelper('numTypeCheck'),
    const CheckedModeHelper('boolTypeCast'),
    const CheckedModeHelper('boolTypeCheck'),
    const CheckedModeHelper('intTypeCast'),
    const CheckedModeHelper('intTypeCheck'),
    const PropertyCheckedModeHelper('numberOrStringSuperNativeTypeCast'),
    const PropertyCheckedModeHelper('numberOrStringSuperNativeTypeCheck'),
    const PropertyCheckedModeHelper('numberOrStringSuperTypeCast'),
    const PropertyCheckedModeHelper('numberOrStringSuperTypeCheck'),
    const PropertyCheckedModeHelper('stringSuperNativeTypeCast'),
    const PropertyCheckedModeHelper('stringSuperNativeTypeCheck'),
    const PropertyCheckedModeHelper('stringSuperTypeCast'),
    const PropertyCheckedModeHelper('stringSuperTypeCheck'),
    const CheckedModeHelper('listTypeCast'),
    const CheckedModeHelper('listTypeCheck'),
    const PropertyCheckedModeHelper('listSuperNativeTypeCast'),
    const PropertyCheckedModeHelper('listSuperNativeTypeCheck'),
    const PropertyCheckedModeHelper('listSuperTypeCast'),
    const PropertyCheckedModeHelper('listSuperTypeCheck'),
    const PropertyCheckedModeHelper('interceptedTypeCast'),
    const PropertyCheckedModeHelper('interceptedTypeCheck'),
    const SubtypeCheckedModeHelper('subtypeCast'),
    const SubtypeCheckedModeHelper('assertSubtype'),
    const TypeVariableCheckedModeHelper('subtypeOfRuntimeTypeCast'),
    const TypeVariableCheckedModeHelper('assertSubtypeOfRuntimeType'),
    const PropertyCheckedModeHelper('propertyTypeCast'),
    const PropertyCheckedModeHelper('propertyTypeCheck'),
    const FunctionTypeRepresentationCheckedModeHelper('functionTypeCast'),
    const FunctionTypeRepresentationCheckedModeHelper('functionTypeCheck'),
    const FutureOrRepresentationCheckedModeHelper('futureOrCast'),
    const FutureOrRepresentationCheckedModeHelper('futureOrCheck'),
  ];

  // Checked mode helpers indexed by name.
  static final Map<String, CheckedModeHelper> checkedModeHelperByName =
      new Map<String, CheckedModeHelper>.fromIterable(helpers,
          key: (helper) => helper.name);

  /// Returns the checked mode helper that will be needed to do a type
  /// check/type cast on [type] at runtime. Note that this method is being
  /// called both by the resolver with interface types (int, String, ...), and
  /// by the SSA backend with implementation types (JSInt, JSString, ...).
  CheckedModeHelper getCheckedModeHelper(
      DartType type, CommonElements commonElements,
      {bool typeCast}) {
    return getCheckedModeHelperInternal(type, commonElements,
        typeCast: typeCast, nativeCheckOnly: false);
  }

  /// Returns the native checked mode helper that will be needed to do a type
  /// check/type cast on [type] at runtime. If no native helper exists for
  /// [type], [:null:] is returned.
  CheckedModeHelper getNativeCheckedModeHelper(
      DartType type, CommonElements commonElements,
      {bool typeCast}) {
    return getCheckedModeHelperInternal(type, commonElements,
        typeCast: typeCast, nativeCheckOnly: true);
  }

  /// Returns the checked mode helper for the type check/type cast for
  /// [type]. If [nativeCheckOnly] is [:true:], only names for native helpers
  /// are returned.
  CheckedModeHelper getCheckedModeHelperInternal(
      DartType type, CommonElements commonElements,
      {bool typeCast, bool nativeCheckOnly}) {
    String name = getCheckedModeHelperNameInternal(type, commonElements,
        typeCast: typeCast, nativeCheckOnly: nativeCheckOnly);
    if (name == null) return null;
    CheckedModeHelper helper = checkedModeHelperByName[name];
    assert(helper != null);
    return helper;
  }

  String getCheckedModeHelperNameInternal(
      DartType type, CommonElements commonElements,
      {bool typeCast, bool nativeCheckOnly}) {
    assert(!type.isTypedef);

    if (type.isTypeVariable) {
      return typeCast
          ? 'subtypeOfRuntimeTypeCast'
          : 'assertSubtypeOfRuntimeType';
    }

    if (type.isFunctionType) {
      return typeCast ? 'functionTypeCast' : 'functionTypeCheck';
    }

    if (type.isFutureOr) {
      return typeCast ? 'futureOrCast' : 'futureOrCheck';
    }

    assert(type.isInterfaceType,
        failedAt(NO_LOCATION_SPANNABLE, "Unexpected type: $type"));
    InterfaceType interfaceType = type;
    ClassEntity element = interfaceType.element;
    bool nativeCheck = true;
    // TODO(13955), TODO(9731).  The test for non-primitive types should use an
    // interceptor.  The interceptor should be an argument to HTypeConversion so
    // that it can be optimized by standard interceptor optimizations.
    //  nativeCheckOnly || emitter.nativeEmitter.requiresNativeIsCheck(element);

    var suffix = typeCast ? 'TypeCast' : 'TypeCheck';
    if (element == commonElements.jsStringClass ||
        element == commonElements.stringClass) {
      if (nativeCheckOnly) return null;
      return 'string$suffix';
    }

    if (element == commonElements.jsDoubleClass ||
        element == commonElements.doubleClass) {
      if (nativeCheckOnly) return null;
      return 'double$suffix';
    }

    if (element == commonElements.jsNumberClass ||
        element == commonElements.numClass) {
      if (nativeCheckOnly) return null;
      return 'num$suffix';
    }

    if (element == commonElements.jsBoolClass ||
        element == commonElements.boolClass) {
      if (nativeCheckOnly) return null;
      return 'bool$suffix';
    }

    if (element == commonElements.jsIntClass ||
        element == commonElements.intClass ||
        element == commonElements.jsUInt32Class ||
        element == commonElements.jsUInt31Class ||
        element == commonElements.jsPositiveIntClass) {
      if (nativeCheckOnly) return null;
      return 'int$suffix';
    }

    if (commonElements.isNumberOrStringSupertype(element)) {
      return nativeCheck
          ? 'numberOrStringSuperNative$suffix'
          : 'numberOrStringSuper$suffix';
    }

    if (commonElements.isStringOnlySupertype(element)) {
      return nativeCheck ? 'stringSuperNative$suffix' : 'stringSuper$suffix';
    }

    if ((element == commonElements.listClass ||
            element == commonElements.jsArrayClass) &&
        type.treatAsRaw) {
      if (nativeCheckOnly) return null;
      return 'list$suffix';
    }

    if (commonElements.isListSupertype(element) && type.treatAsRaw) {
      return nativeCheck ? 'listSuperNative$suffix' : 'listSuper$suffix';
    }

    if (type.isInterfaceType && !type.treatAsRaw) {
      return typeCast ? 'subtypeCast' : 'assertSubtype';
    }

    if (nativeCheck) {
      // TODO(karlklose): can we get rid of this branch when we use
      // interceptors?
      return 'intercepted$suffix';
    } else {
      return 'property$suffix';
    }
  }
}
