// 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.

// @dart = 2.10

import 'package:kernel/ast.dart' as ir;

import '../common/names.dart';
import 'util.dart';

/// Enum for recognized use kinds of `Object.runtimeType`.
enum RuntimeTypeUseKind {
  /// Unknown use of `Object.runtimeType`. This is the fallback value if the
  /// usage didn't match any of the recognized patterns.
  unknown,

  /// `Object.runtimeType` used in a pattern like
  /// `a.runtimeType == b.runtimeType`.
  equals,

  /// `Object.runtimeType` used in a pattern like `'${e.runtimeType}'` or
  /// `e.runtimeType.toString()`.
  string,
}

/// Data object use for computing static type information on uses of
/// `Object.runtimeType`.
class RuntimeTypeUseData {
  /// The use kind of `Object.runtimeType`.
  final RuntimeTypeUseKind kind;

  /// The property get for the left (or single) occurrence of `.runtimeType`.
  // TODO(johnniwinther): Change this to `InstanceGet` when the old method
  // invocation encoding is no longer used.
  final ir.Expression leftRuntimeTypeExpression;

  /// The receiver expression.
  final ir.Expression receiver;

  /// The static type of the receiver expression. This is set in the static type
  /// visitor.
  ir.DartType receiverType;

  /// The property get for the right occurrence of `.runtimeType` when [kind]
  /// is `RuntimeTypeUseKind.equals`.
  // TODO(johnniwinther): Change this to `InstanceGet` when the old method
  // invocation encoding is no longer used.
  final ir.Expression rightRuntimeTypeExpression;

  /// The argument expression if [kind] is `RuntimeTypeUseKind.equals`.
  final ir.Expression argument;

  /// The static type of the argument expression. This is set in the static type
  /// visitor.
  ir.DartType argumentType;

  RuntimeTypeUseData(this.kind, this.leftRuntimeTypeExpression, this.receiver,
      this.rightRuntimeTypeExpression, this.argument);

  bool get isComplete {
    switch (kind) {
      case RuntimeTypeUseKind.unknown:
      case RuntimeTypeUseKind.string:
        return receiverType != null;
      case RuntimeTypeUseKind.equals:
        return receiverType != null && argumentType != null;
    }
    throw UnsupportedError("Unexpected RuntimeTypeUseKind $kind.");
  }

  @override
  String toString() {
    return "RuntimeTypeUseData(kind=$kind,"
        "receiverGet=$leftRuntimeTypeExpression,receiver=$receiver,"
        "receiverType=$receiverType,argumentGet=$rightRuntimeTypeExpression,"
        "argument=$argument,argumentType=$argumentType)";
  }
}

/// Computes the [RuntimeTypeUseData] corresponding to the `e.runtimeType`
/// [node].
///
/// [cache] is used to ensure that only one [RuntimeTypeUseData] object is
/// created per case, even for the `==` case.
// TODO(johnniwinther): Change [cache] key and [node] to `InstanceGet` when the
// old method invocation encoding is no longer used.
RuntimeTypeUseData computeRuntimeTypeUse(
    Map<ir.Expression, RuntimeTypeUseData> cache, ir.Expression node) {
  RuntimeTypeUseData receiverData = cache[node];
  if (receiverData != null) return receiverData;

  /// Returns `true` if [node] is of the form `e.runtimeType`.
  bool isGetRuntimeType(ir.TreeNode node) {
    return node is ir.InstanceGet &&
            node.name.text == Identifiers.runtimeType_ ||
        node is ir.DynamicGet && node.name.text == Identifiers.runtimeType_;
  }

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

  assert(isGetRuntimeType(node));
  // TODO(johnniwinther): Replace this with `node.receiver` when the old method
  // invocation encoding is no longer used.
  _RuntimeTypeAccess runtimeTypeAccess = _getRuntimeTypeAccess(node);
  assert(runtimeTypeAccess != null);

  // TODO(johnniwinther): Change [receiverGet] and [argumentGet] to
  // `InstanceGet` when the old method invocation encoding is no longer used.
  // TODO(johnniwinther): Special-case `this.runtimeType`.
  ir.Expression receiverGet;
  ir.Expression receiver;
  ir.Expression argumentGet;
  ir.Expression argument;
  RuntimeTypeUseKind kind;

  if (runtimeTypeAccess.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;
          receiverGet = node;
        }
      } else if (_isObjectMethodInvocation(nullAware.parent)) {
        _EqualsInvocation equalsInvocation =
            _getEqualsInvocation(nullAware.parent);
        if (equalsInvocation != null &&
            equalsInvocation.left == nullAware.let) {
          // Detected
          //
          //  e0?.runtimeType == other
          _RuntimeTypeAccess otherGetRuntimeType =
              _getRuntimeTypeAccess(equalsInvocation.right);
          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;
            receiverGet = node;
            argument = otherGetRuntimeType.receiver;
            argumentGet = otherGetRuntimeType.node;
          }

          NullAwareExpression otherNullAware =
              getNullAwareExpression(equalsInvocation.right);
          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;
            receiverGet = node;
            argument = otherNullAware.receiver;
            argumentGet = otherNullAware.expression;
          }
        } 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;
          receiverGet = node;
        }
      } else if (nullAware.parent is ir.Arguments &&
          _isObjectMethodInvocation(nullAware.parent.parent)) {
        _EqualsInvocation equalsInvocation =
            _getEqualsInvocation(nullAware.parent.parent);
        if (equalsInvocation != null &&
            equalsInvocation.right == nullAware.let) {
          // [nullAware] is the right hand side of ==.

          _RuntimeTypeAccess otherGetRuntimeType =
              _getRuntimeTypeAccess(equalsInvocation.left);
          NullAwareExpression otherNullAware =
              getNullAwareExpression(equalsInvocation.left);

          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;
            receiverGet = otherGetRuntimeType.node;
            argument = nullAware.receiver;
            argumentGet = node;
          }

          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;
            receiverGet = otherNullAware.expression;
            argument = nullAware.receiver;
            argumentGet = node;
          }
        }
      } 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;
        receiverGet = node;
      } else {
        // Default to unknown
        //
        //     e?.runtimeType
        //        ^
        // encoded as
        //
        //     let #t1 = e in #t1 == null ? null : #t1.runtimeType
        //                                         ^
        kind = RuntimeTypeUseKind.unknown;
        receiver = nullAware.receiver;
        receiverGet = node;
      }
    }
  } 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 = runtimeTypeAccess.receiver;
      receiverGet = node;
    }
  } else if (_isObjectMethodInvocation(node.parent)) {
    _EqualsInvocation equalsInvocation = _getEqualsInvocation(node.parent);
    if (equalsInvocation != null && equalsInvocation.left == node) {
      // [node] is the left hand side of ==.

      _RuntimeTypeAccess otherGetRuntimeType =
          _getRuntimeTypeAccess(equalsInvocation.right);
      NullAwareExpression nullAware =
          getNullAwareExpression(equalsInvocation.right);
      if (otherGetRuntimeType != null) {
        // Detected
        //
        //     e0.runtimeType == e1.runtimeType
        //        ^
        // encoded as
        //
        //     e0.runtimeType.==(e1.runtimeType)
        //        ^
        kind = RuntimeTypeUseKind.equals;
        receiver = runtimeTypeAccess.receiver;
        receiverGet = node;
        argument = otherGetRuntimeType.receiver;
        argumentGet = otherGetRuntimeType.node;
      } 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 = runtimeTypeAccess.receiver;
        receiverGet = node;
        argument = nullAware.receiver;
        argumentGet = nullAware.expression;
      }
    } else if (isInvokeToString(node.parent)) {
      // Detected
      //
      //     e.runtimeType.toString()
      //       ^
      kind = RuntimeTypeUseKind.string;
      receiver = runtimeTypeAccess.receiver;
      receiverGet = node;
    }
  } else if (node.parent is ir.Arguments &&
      _isObjectMethodInvocation(node.parent.parent)) {
    _EqualsInvocation _equalsInvocation =
        _getEqualsInvocation(node.parent.parent);
    if (_equalsInvocation != null && _equalsInvocation.right == node) {
      // [node] is the right hand side of ==.
      _RuntimeTypeAccess otherGetRuntimeType =
          _getRuntimeTypeAccess(_equalsInvocation.left);
      NullAwareExpression nullAware =
          getNullAwareExpression(_equalsInvocation.left);

      if (otherGetRuntimeType != null) {
        // Detected
        //
        //     e0.runtimeType == e1.runtimeType
        //                          ^
        // encoded as
        //
        //     e0.runtimeType.==(e1.runtimeType)
        //                          ^
        kind = RuntimeTypeUseKind.equals;
        receiver = otherGetRuntimeType.receiver;
        receiverGet = otherGetRuntimeType.node;
        argument = runtimeTypeAccess.receiver;
        argumentGet = node;
      } 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;
        receiverGet = nullAware.expression;
        argument = runtimeTypeAccess.receiver;
        argumentGet = node;
      }
    }
  } else if (node.parent is ir.StringConcatenation) {
    // Detected
    //
    //     '${e.runtimeType}'
    //          ^
    kind = RuntimeTypeUseKind.string;
    receiver = runtimeTypeAccess.receiver;
    receiverGet = node;
  }

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

  RuntimeTypeUseData data =
      RuntimeTypeUseData(kind, receiverGet, receiver, argumentGet, argument);
  cache[receiverGet] = data;
  if (argumentGet != null) {
    cache[argumentGet] = data;
  }

  assert(receiverGet != null, "Missing receiverGet in $data for $node.");
  assert(!(argument != null && argumentGet == null),
      "Missing argumentGet in $data for $node.");
  assert(
      receiverGet != argumentGet, "Duplicate property get in $data for $node.");
  return data;
}

/// Returns `true` if [node] is a potential invocation of an Object method.
bool _isObjectMethodInvocation(ir.TreeNode node) {
  return node is ir.InstanceInvocation || node is ir.EqualsCall;
}

/// Returns the [_RuntimeTypeAccess] corresponding to [node] if it is an access
/// of `.runtimeType`, and `null` otherwise.
_RuntimeTypeAccess _getRuntimeTypeAccess(ir.TreeNode node) {
  if (node is ir.InstanceGet && node.name.text == 'runtimeType') {
    return _RuntimeTypeAccess(node, node.receiver);
  } else if (node is ir.DynamicGet && node.name.text == 'runtimeType') {
    return _RuntimeTypeAccess(node, node.receiver);
  }
  return null;
}

class _RuntimeTypeAccess {
  final ir.Expression node;
  final ir.Expression receiver;

  _RuntimeTypeAccess(this.node, this.receiver);
}

/// Returns the [_EqualsInvocation] corresponding to [node] if it is a call to
/// of `==`, and `null` otherwise.
_EqualsInvocation _getEqualsInvocation(ir.TreeNode node) {
  if (node is ir.EqualsCall) {
    return _EqualsInvocation(node, node.left, node.right);
  }
  return null;
}

class _EqualsInvocation {
  final ir.Expression node;
  final ir.Expression left;
  final ir.Expression right;

  _EqualsInvocation(this.node, this.left, this.right);
}
