// Copyright (c) 2020, the R8 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.
package com.android.tools.r8.ir.optimize.info.bridge;

import static com.android.tools.r8.ir.code.Opcodes.ARGUMENT;
import static com.android.tools.r8.ir.code.Opcodes.ASSUME;
import static com.android.tools.r8.ir.code.Opcodes.CHECK_CAST;
import static com.android.tools.r8.ir.code.Opcodes.INVOKE_VIRTUAL;
import static com.android.tools.r8.ir.code.Opcodes.RETURN;

import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.ir.code.CheckCast;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.InvokeMethod;
import com.android.tools.r8.ir.code.InvokeVirtual;
import com.android.tools.r8.ir.code.Return;
import com.android.tools.r8.ir.code.Value;
import com.android.tools.r8.utils.BooleanUtils;

public class BridgeAnalyzer {

  /** Returns a {@link BridgeInfo} object describing this method if it is recognized as a bridge. */
  public static BridgeInfo analyzeMethod(DexEncodedMethod method, IRCode code) {
    // TODO(b/154263783): Consider computing BridgeInfo also for non-declared bridges.
    if (!method.isBridge() || code.blocks.size() > 1) {
      return failure();
    }

    // Scan through the instructions one-by-one. We expect a sequence of Argument instructions,
    // followed by a (possibly empty) sequence of CheckCast instructions, followed by a single
    // InvokeMethod instruction, followed by an optional CheckCast instruction, followed by a Return
    // instruction.
    InvokeVirtual uniqueInvoke = null;
    CheckCast uniqueReturnCast = null;
    for (Instruction instruction : code.entryBlock().getInstructions()) {
      switch (instruction.opcode()) {
        case ARGUMENT:
          break;

        case ASSUME:
          break;

        case CHECK_CAST:
          {
            CheckCast checkCast = instruction.asCheckCast();
            if (!analyzeCheckCast(method, checkCast, uniqueInvoke)) {
              return failure();
            }
            // If we have moved past the single invoke instruction, then record that this cast is
            // the cast instruction for the result value.
            if (uniqueInvoke != null) {
              if (uniqueReturnCast != null) {
                return failure();
              }
              uniqueReturnCast = checkCast;
            }
            break;
          }

        case INVOKE_VIRTUAL:
          {
            if (uniqueInvoke != null) {
              return failure();
            }
            InvokeVirtual invoke = instruction.asInvokeVirtual();
            if (!analyzeInvokeVirtual(invoke)) {
              return failure();
            }
            // Record that we have seen the single invoke instruction.
            uniqueInvoke = invoke;
            break;
          }

        case RETURN:
          if (!analyzeReturn(instruction.asReturn(), uniqueInvoke, uniqueReturnCast)) {
            return failure();
          }
          break;

        default:
          return failure();
      }
    }

    assert uniqueInvoke != null;
    return new VirtualBridgeInfo(uniqueInvoke.getInvokedMethod());
  }

  private static boolean analyzeCheckCast(
      DexEncodedMethod method, CheckCast checkCast, InvokeMethod invoke) {
    return invoke == null
        ? analyzeCheckCastBeforeInvoke(checkCast)
        : analyzeCheckCastAfterInvoke(method, checkCast, invoke);
  }

  private static boolean analyzeCheckCastBeforeInvoke(CheckCast checkCast) {
    Value object = checkCast.object().getAliasedValue();
    // It must be casting one of the arguments.
    if (!object.isArgument()) {
      return false;
    }
    int argumentIndex = object.definition.asArgument().getIndex();
    Value castValue = checkCast.outValue();
    // The out value cannot have any phi users since there is only one block.
    assert !castValue.hasPhiUsers();
    // It is not allowed to have any other users than the invoke instruction.
    if (castValue.hasDebugUsers() || !castValue.hasSingleUniqueUser()) {
      return false;
    }
    InvokeMethod invoke = castValue.singleUniqueUser().asInvokeMethod();
    if (invoke == null) {
      return false;
    }
    if (invoke.arguments().size() <= argumentIndex) {
      return false;
    }
    int parameterIndex = argumentIndex - BooleanUtils.intValue(invoke.isInvokeMethodWithReceiver());
    // It is not allowed to cast the receiver.
    if (parameterIndex == -1) {
      return false;
    }
    // The type of the cast must match the type of the parameter.
    if (checkCast.getType() != invoke.getInvokedMethod().proto.getParameter(parameterIndex)) {
      return false;
    }
    // It must be forwarded at the same argument index.
    Value argument = invoke.getArgument(argumentIndex);
    if (argument != castValue) {
      return false;
    }
    return true;
  }

  private static boolean analyzeCheckCastAfterInvoke(
      DexEncodedMethod method, CheckCast checkCast, InvokeMethod invoke) {
    Value returnValue = invoke.outValue();
    Value uncastValue = checkCast.object().getAliasedValue();
    Value castValue = checkCast.outValue();
    // The out value cannot have any phi users since there is only one block.
    assert !castValue.hasPhiUsers();
    // It must cast the result to the return type of the enclosing method and return the cast value.
    return uncastValue == returnValue
        && checkCast.getType() == method.returnType()
        && !castValue.hasDebugUsers()
        && castValue.hasSingleUniqueUser()
        && castValue.singleUniqueUser().isReturn();
  }

  private static boolean analyzeInvokeVirtual(InvokeVirtual invoke) {
    // All of the forwarded arguments of the enclosing method must be in the same argument position.
    for (int argumentIndex = 0; argumentIndex < invoke.arguments().size(); argumentIndex++) {
      Value argument = invoke.getArgument(argumentIndex);
      if (argument.isArgument() && argumentIndex != argument.definition.asArgument().getIndex()) {
        return false;
      }
    }
    return true;
  }

  private static boolean analyzeReturn(Return ret, InvokeMethod invoke, CheckCast returnCast) {
    // If we haven't seen an invoke this is not a bridge.
    if (invoke == null) {
      return false;
    }
    // It must not return a value, or the return value must be the result value of the invoke.
    return ret.isReturnVoid()
        || ret.returnValue() == (returnCast != null ? returnCast : invoke).outValue();
  }

  private static BridgeInfo failure() {
    return null;
  }
}
