// Copyright (c) 2024, 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.optimize.compose;

import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.code.And;
import com.android.tools.r8.ir.code.Argument;
import com.android.tools.r8.ir.code.ConstNumber;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.LinearFlowInstructionListIterator;
import com.android.tools.r8.ir.code.Or;
import com.android.tools.r8.ir.code.Return;
import com.android.tools.r8.ir.code.Shl;
import com.android.tools.r8.ir.code.Shr;

public class ComposeUtils {

  /**
   * Checks if the given code object executes the following instructions.
   *
   * <pre>
   * private const val changedLowBitMask = 0b001_001_001_001_001_001_001_001_001_001_0
   * private const val changedHighBitMask = changedLowBitMask shl 1
   * private const val changedMask = (changedLowBitMask or changedHighBitMask).inv()
   *
   * internal fun updateChangedFlags(flags: Int): Int {
   *     val lowBits = flags and changedLowBitMask
   *     val highBits = flags and changedHighBitMask
   *     return ((flags and changedMask) or
   *         (lowBits or (highBits shr 1)) or ((lowBits shl 1) and highBits))
   * }
   * </pre>
   */
  public static boolean isUpdateChangedFlags(IRCode code, DexItemFactory factory) {
    ProgramMethod method = code.context();
    if (!method.getAccessFlags().isStatic()
        || method.getArity() != 1
        || method.getParameter(0).isNotIdenticalTo(factory.intType)
        || method.getReturnType().isNotIdenticalTo(factory.intType)) {
      return false;
    }
    LinearFlowInstructionListIterator instructionIterator =
        new LinearFlowInstructionListIterator(code);
    Argument argument = instructionIterator.next().asArgument();
    assert argument != null;
    ConstNumber changedLowBitMask =
        instructionIterator.next().asConstNumber(0b001_001_001_001_001_001_001_001_001_001_0);
    if (changedLowBitMask == null) {
      return false;
    }
    And lowBits =
        instructionIterator.next().asAnd(argument.outValue(), changedLowBitMask.outValue());
    if (lowBits == null) {
      return false;
    }
    ConstNumber changedHighBitMask =
        instructionIterator.next().asConstNumber(0b010_010_010_010_010_010_010_010_010_010_0);
    if (changedHighBitMask == null) {
      return false;
    }
    And highBits =
        instructionIterator.next().asAnd(argument.outValue(), changedHighBitMask.outValue());
    if (highBits == null) {
      return false;
    }
    ConstNumber changedMask =
        instructionIterator.next().asConstNumber(0b1_100_100_100_100_100_100_100_100_100_100_1);
    if (changedMask == null) {
      return false;
    }
    And changedBits = instructionIterator.next().asAnd(argument.outValue(), changedMask.outValue());
    if (changedBits == null) {
      return false;
    }
    ConstNumber one = instructionIterator.next().asConstNumber(1);
    if (one == null) {
      return false;
    }
    Shr highBitsShrOne = instructionIterator.next().asShr(highBits.outValue(), one.outValue());
    if (highBitsShrOne == null) {
      return false;
    }
    Or lowBitsOrHighBitsShrOne =
        instructionIterator.next().asOr(lowBits.outValue(), highBitsShrOne.outValue());
    if (lowBitsOrHighBitsShrOne == null) {
      return false;
    }
    Or changedBitsOrLowBitsOrHighBitsShrOne =
        instructionIterator.next().asOr(changedBits.outValue(), lowBitsOrHighBitsShrOne.outValue());
    if (changedBitsOrLowBitsOrHighBitsShrOne == null) {
      return false;
    }
    ConstNumber oneAgain = instructionIterator.next().asConstNumber(1);
    if (oneAgain == null) {
      return false;
    }
    Shl lowBitsShlOne = instructionIterator.next().asShl(lowBits.outValue(), oneAgain.outValue());
    if (lowBitsShlOne == null) {
      return false;
    }
    And lowBitsShlOneAndHighBits =
        instructionIterator.next().asAnd(lowBitsShlOne.outValue(), highBits.outValue());
    if (lowBitsShlOneAndHighBits == null) {
      return false;
    }
    Or result =
        instructionIterator
            .next()
            .asOr(
                changedBitsOrLowBitsOrHighBitsShrOne.outValue(),
                lowBitsShlOneAndHighBits.outValue());
    if (result == null) {
      return false;
    }
    Return theReturn = instructionIterator.next().asReturn();
    return theReturn != null && theReturn.returnValue() == result.outValue();
  }
}
