// Copyright (c) 2016, 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:kernel/ast.dart' as ir;

import '../common/names.dart';
import '../elements/types.dart';
import '../ir/util.dart';
import '../universe/feature.dart';
import 'element_map.dart';

/// Computes the [RuntimeTypeUse] corresponding to the `e.runtimeType` [node].
RuntimeTypeUse computeRuntimeTypeUse(
    KernelToElementMap elementMap, ir.PropertyGet node) {
  /// Returns `true` if [node] is of the form `e.runtimeType`.
  bool isGetRuntimeType(ir.TreeNode node) {
    return node is ir.PropertyGet && node.name.name == Identifiers.runtimeType_;
  }

  /// Returns [node] if [node] is of the form `e.runtimeType` and `null`
  /// otherwise.
  ir.PropertyGet asGetRuntimeType(ir.TreeNode node) {
    return isGetRuntimeType(node) ? node : null;
  }

  /// Returns `true` if [node] is of the form `e.toString()`.
  bool isInvokeToString(ir.TreeNode node) {
    return node is ir.MethodInvocation && node.name.name == 'toString';
  }

  assert(isGetRuntimeType(node));

  // TODO(johnniwinther): Special-case `this.runtimeType`.
  ir.Expression receiver;
  ir.Expression argument;
  RuntimeTypeUseKind kind;

  if (node.receiver is ir.VariableGet &&
      node.parent is ir.ConditionalExpression &&
      node.parent.parent is ir.Let) {
    NullAwareExpression nullAware = getNullAwareExpression(node.parent.parent);
    if (nullAware != null) {
      // The node is of the form:
      //
      //     let #t1 = e in #t1 == null ? null : #t1.runtimeType
      //                                             ^

      if (nullAware.parent is ir.VariableDeclaration &&
          nullAware.parent.parent is ir.Let) {
        NullAwareExpression outer =
            getNullAwareExpression(nullAware.parent.parent);
        if (outer != null &&
            outer.receiver == nullAware.let &&
            isInvokeToString(outer.expression)) {
          // Detected
          //
          //     e?.runtimeType?.toString()
          //        ^
          // encoded as
          //
          //     let #t2 = (let #t1 = e in #t1 == null ? null : #t1.runtimeType)
          //                                                        ^
          //        in #t2 == null ? null : #t2.toString()
          //
          kind = RuntimeTypeUseKind.string;
          receiver = nullAware.receiver;
        }
      } else if (nullAware.parent is ir.MethodInvocation) {
        ir.MethodInvocation methodInvocation = nullAware.parent;
        if (methodInvocation.receiver == nullAware.let &&
            methodInvocation.name.name == '==') {
          // Detected
          //
          //  e0?.runtimeType == other
          ir.PropertyGet otherGetRuntimeType =
              asGetRuntimeType(methodInvocation.arguments.positional.first);
          if (otherGetRuntimeType != null) {
            // Detected
            //
            //     e0?.runtimeType == e1.runtimeType
            //         ^
            // encoded as
            //
            //     (let #t1 = e0 in #t1 == null ? null : #t1.runtimeType)
            //                                               ^
            //        .==(e1.runtimeType)
            kind = RuntimeTypeUseKind.equals;
            receiver = nullAware.receiver;
            argument = otherGetRuntimeType.receiver;
          }

          NullAwareExpression otherNullAware = getNullAwareExpression(
              methodInvocation.arguments.positional.first);
          if (otherNullAware != null &&
              isGetRuntimeType(otherNullAware.expression)) {
            // Detected
            //
            //     e0?.runtimeType == e1?.runtimeType
            //         ^
            // encoded as
            //
            //     (let #t1 = e0 in #t1 == null ? null : #t1.runtimeType)
            //                                               ^
            //         .==(let #t2 = e1 in #t2 == null ? null : #t2.runtimeType)
            //
            kind = RuntimeTypeUseKind.equals;
            receiver = nullAware.receiver;
            argument = otherNullAware.receiver;
          }
        } else if (isInvokeToString(nullAware.parent)) {
          // Detected
          //
          //     e?.runtimeType.toString()
          //        ^
          // encoded as
          //
          //     (let #t1 = e in #t1 == null ? null : #t1.runtimeType)
          //                                          ^
          //         .toString()
          //
          kind = RuntimeTypeUseKind.string;
          receiver = nullAware.receiver;
        }
      } else if (nullAware.parent is ir.Arguments &&
          nullAware.parent.parent is ir.MethodInvocation) {
        ir.MethodInvocation methodInvocation = nullAware.parent.parent;
        if (methodInvocation.name.name == '==' &&
            methodInvocation.arguments.positional.first == nullAware.let) {
          // [nullAware] is the right hand side of ==.

          ir.PropertyGet otherGetRuntimeType =
              asGetRuntimeType(methodInvocation.receiver);
          NullAwareExpression otherNullAware =
              getNullAwareExpression(methodInvocation.receiver);

          if (otherGetRuntimeType != null) {
            // Detected
            //
            //     e0.runtimeType == e1?.runtimeType
            //                           ^
            // encoded as
            //
            //     e0.runtimeType.==(
            //         let #t1 = e1 in #t1 == null ? null : #t1.runtimeType)
            //                                                  ^
            kind = RuntimeTypeUseKind.equals;
            receiver = otherGetRuntimeType.receiver;
            argument = nullAware.receiver;
          }

          if (otherNullAware != null &&
              isGetRuntimeType(otherNullAware.expression)) {
            // Detected
            //
            //     e0?.runtimeType == e1?.runtimeType
            //                            ^
            // encoded as
            //
            //     (let #t1 = e0 in #t1 == null ? null : #t1.runtimeType)
            //         .==(let #t2 = e1 in #t2 == null ? null : #t2.runtimeType)
            //                                                      ^
            kind = RuntimeTypeUseKind.equals;
            receiver = otherNullAware.receiver;
            argument = nullAware.receiver;
          }
        }
      } else if (nullAware.parent is ir.StringConcatenation) {
        // Detected
        //
        //     '${e?.runtimeType}'
        //           ^
        // encoded as
        //
        //     '${let #t1 = e in #t1 == null ? null : #t1.runtimeType}'
        //                                                ^
        kind = RuntimeTypeUseKind.string;
        receiver = nullAware.receiver;
      } else {
        // Default to unknown
        //
        //     e?.runtimeType
        //        ^
        // encoded as
        //
        //     let #t1 = e in #t1 == null ? null : #t1.runtimeType
        //                                         ^
        kind = RuntimeTypeUseKind.unknown;
        receiver = nullAware.receiver;
      }
    }
  } else if (node.parent is ir.VariableDeclaration &&
      node.parent.parent is ir.Let) {
    NullAwareExpression nullAware = getNullAwareExpression(node.parent.parent);
    if (nullAware != null && isInvokeToString(nullAware.expression)) {
      // Detected
      //
      //     e.runtimeType?.toString()
      //       ^
      // encoded as
      //
      //     let #t1 = e.runtimeType in #t1 == null ? null : #t1.toString()
      //                 ^
      kind = RuntimeTypeUseKind.string;
      receiver = node.receiver;
    }
  } else if (node.parent is ir.MethodInvocation) {
    ir.MethodInvocation methodInvocation = node.parent;
    if (methodInvocation.name.name == '==' &&
        methodInvocation.receiver == node) {
      // [node] is the left hand side of ==.

      ir.PropertyGet otherGetRuntimeType =
          asGetRuntimeType(methodInvocation.arguments.positional.first);
      NullAwareExpression nullAware =
          getNullAwareExpression(methodInvocation.arguments.positional.first);
      if (otherGetRuntimeType != null) {
        // Detected
        //
        //     e0.runtimeType == e1.runtimeType
        //        ^
        // encoded as
        //
        //     e0.runtimeType.==(e1.runtimeType)
        //        ^
        kind = RuntimeTypeUseKind.equals;
        receiver = node.receiver;
        argument = otherGetRuntimeType.receiver;
      } else if (nullAware != null && isGetRuntimeType(nullAware.expression)) {
        // Detected
        //
        //     e0.runtimeType == e1?.runtimeType
        //        ^
        // encoded as
        //
        //     e0.runtimeType.==(
        //        ^
        //         let #t1 = e1 in #t1 == null ? null : #t1.runtimeType)
        kind = RuntimeTypeUseKind.equals;
        receiver = node.receiver;
        argument = nullAware.receiver;
      }
    } else if (isInvokeToString(node.parent)) {
      // Detected
      //
      //     e.runtimeType.toString()
      //       ^
      kind = RuntimeTypeUseKind.string;
      receiver = node.receiver;
    }
  } else if (node.parent is ir.Arguments &&
      node.parent.parent is ir.MethodInvocation) {
    ir.MethodInvocation methodInvocation = node.parent.parent;
    if (methodInvocation.name.name == '==' &&
        methodInvocation.arguments.positional.first == node) {
      // [node] is the right hand side of ==.
      ir.PropertyGet otherGetRuntimeType =
          asGetRuntimeType(methodInvocation.receiver);
      NullAwareExpression nullAware =
          getNullAwareExpression(methodInvocation.receiver);

      if (otherGetRuntimeType != null) {
        // Detected
        //
        //     e0.runtimeType == e1.runtimeType
        //                          ^
        // encoded as
        //
        //     e0.runtimeType.==(e1.runtimeType)
        //                          ^
        kind = RuntimeTypeUseKind.equals;
        receiver = otherGetRuntimeType.receiver;
        argument = node.receiver;
      } else if (nullAware != null && isGetRuntimeType(nullAware.expression)) {
        // Detected
        //
        //     e0?.runtimeType == e1.runtimeType
        //                           ^
        // encoded as
        //
        //     (let #t1 = e0 in #t1 == null ? null : #t1.runtimeType)
        //         .==(e1.runtimeType)
        //                ^
        kind = RuntimeTypeUseKind.equals;
        receiver = nullAware.receiver;
        argument = node.receiver;
      }
    }
  } else if (node.parent is ir.StringConcatenation) {
    // Detected
    //
    //     '${e.runtimeType}'
    //          ^
    kind = RuntimeTypeUseKind.string;
    receiver = node.receiver;
  }

  if (kind == null) {
    // Default to unknown
    //
    //     e.runtimeType
    //       ^
    kind = RuntimeTypeUseKind.unknown;
    receiver = node.receiver;
  }

  DartType receiverType = elementMap.getStaticType(receiver);
  DartType argumentType =
      argument == null ? null : elementMap.getStaticType(argument);
  return new RuntimeTypeUse(kind, receiverType, argumentType);
}
