// Copyright (c) 2017, 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;

import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.code.ArrayGet;
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.InvokeVirtual;
import com.android.tools.r8.ir.code.StaticGet;
import com.android.tools.r8.shaking.Enqueuer.AppInfoWithLiveness;
import it.unimi.dsi.fastutil.ints.Int2ReferenceMap;
import it.unimi.dsi.fastutil.objects.Reference2IntMap;

public class SwitchUtils {

  public static final class EnumSwitchInfo {
    public final DexType enumClass;
    public final Instruction ordinalInvoke;
    public final Instruction arrayGet;
    public final Instruction staticGet;
    public final Int2ReferenceMap<DexField> indexMap;
    public final Reference2IntMap<DexField> ordinalsMap;

    private EnumSwitchInfo(DexType enumClass,
        Instruction ordinalInvoke,
        Instruction arrayGet, Instruction staticGet,
        Int2ReferenceMap<DexField> indexMap,
        Reference2IntMap<DexField> ordinalsMap) {
      this.enumClass = enumClass;
      this.ordinalInvoke = ordinalInvoke;
      this.arrayGet = arrayGet;
      this.staticGet = staticGet;
      this.indexMap = indexMap;
      this.ordinalsMap = ordinalsMap;
    }
  }

  /**
   * Looks for a switch statement over the enum companion class of the form
   *
   * <blockquote><pre>
   * switch(CompanionClass.$switchmap$field[enumValue.ordinal()]) {
   *   ...
   * }
   * </pre></blockquote>
   *
   * and extracts the components and the index and ordinal maps. See
   * {@link EnumOrdinalMapCollector} and
   * {@link SwitchMapCollector} for details.
   */
  public static EnumSwitchInfo analyzeSwitchOverEnum(Instruction switchInsn,
      AppInfoWithLiveness appInfo) {
    Instruction input = switchInsn.inValues().get(0).definition;
    if (input == null || !input.isArrayGet()) {
      return null;
    }
    ArrayGet arrayGet = input.asArrayGet();
    Instruction index = arrayGet.index().definition;
    if (index == null || !index.isInvokeVirtual()) {
      return null;
    }
    InvokeVirtual ordinalInvoke = index.asInvokeVirtual();
    DexMethod ordinalMethod = ordinalInvoke.getInvokedMethod();
    DexClass enumClass = appInfo.definitionFor(ordinalMethod.holder);
    DexItemFactory dexItemFactory = appInfo.dexItemFactory;
    // After member rebinding, enumClass will be the actual java.lang.Enum class.
    if (enumClass == null
        || (!enumClass.accessFlags.isEnum() && enumClass.type != dexItemFactory.enumType)
        || ordinalMethod.name != dexItemFactory.ordinalMethodName
        || ordinalMethod.proto.returnType != dexItemFactory.intType
        || !ordinalMethod.proto.parameters.isEmpty()) {
      return null;
    }
    Instruction array = arrayGet.array().definition;
    if (array == null || !array.isStaticGet()) {
      return null;
    }
    StaticGet staticGet = array.asStaticGet();
    Int2ReferenceMap<DexField> indexMap = appInfo.getSwitchMapFor(staticGet.getField());
    if (indexMap == null || indexMap.isEmpty()) {
      return null;
    }
    // Due to member rebinding, only the fields are certain to provide the actual enums
    // class.
    DexType enumType = indexMap.values().iterator().next().getHolder();
    Reference2IntMap<DexField> ordinalsMap = appInfo.getOrdinalsMapFor(enumType);
    if (ordinalsMap == null) {
      return null;
    }
    return new EnumSwitchInfo(enumType, ordinalInvoke, arrayGet, staticGet, indexMap,
        ordinalsMap);
  }


}
