// 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.analysis.proto;

import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.google.common.collect.Sets;
import java.util.Set;

/**
 * EnumLite proto enums include the following code: <code>
 * private static final EnumLiteMap<ProtoEnum> internalValueMap =
 *   new EnumLiteMap<ProtoEnum>() {
 *     public ProtoEnum findValueByNumber(int number) {
 *       return ProtoEnum.forNumber(number);
 *     }
 *   };
 * </code>
 *
 * <p>If the field internalValueMap on the EnumLite is effectively unused (never read), the
 * anonymous subclass of EnumLiteMap is effectively dead. R8 figures that out however too late,
 * during the second round of tree shaking, and the bridge findValueByNumber in the anonymous
 * subclass of EnumLiteMap prevents the EnumLite to be unboxed.
 *
 * <p>This class prematurely clears the virtual methods of the anonymous subclasses of EnumLiteMap,
 * when it can prove that the internalValueMap field of the corresponding EnumLite is never read.
 */
public class EnumLiteProtoShrinker {

  private AppView<AppInfoWithLiveness> appView;
  private ProtoReferences references;
  private Set<DexType> deadEnumLiteMaps = Sets.newIdentityHashSet();

  public EnumLiteProtoShrinker(AppView<AppInfoWithLiveness> appView, ProtoReferences references) {
    this.appView = appView;
    this.references = references;
  }

  public Set<DexType> getDeadEnumLiteMaps() {
    return deadEnumLiteMaps;
  }

  private DexField createInternalValueMapField(DexType holder) {
    return appView
        .dexItemFactory()
        .createField(holder, references.enumLiteMapType, references.internalValueMapFieldName);
  }

  public void clearDeadEnumLiteMaps() {
    assert appView.options().protoShrinking().isEnumLiteProtoShrinkingEnabled();
    // The optimization only enables further enums to be unboxed, no point to run it if enum
    // unboxing is disabled.
    if (!appView.options().enableEnumUnboxing) {
      return;
    }
    // The optimization relies on shrinking and member value propagation to actually clear
    // the anonymous subclasses of EnumLiteMap.
    if (!appView.options().isShrinking() || !appView.options().enableValuePropagation) {
      return;
    }
    internalClearDeadEnumLiteMaps();
  }

  private void internalClearDeadEnumLiteMaps() {
    for (DexProgramClass clazz : appView.appInfo().classes()) {
      if (isDeadEnumLiteMap(clazz)) {
        deadEnumLiteMaps.add(clazz.getType());
        // Clears the EnumLiteMap methods to avoid them being IR processed.
        clazz.setVirtualMethods(DexEncodedMethod.EMPTY_ARRAY);
      }
    }
  }

  public boolean isDeadEnumLiteMap(DexProgramClass clazz) {
    if (clazz.getInterfaces().contains(references.enumLiteMapType)) {
      DexProgramClass enumLite = computeCorrespondingEnumLite(clazz);
      if (enumLite != null) {
        DexEncodedField field =
            enumLite.lookupField(createInternalValueMapField(enumLite.getType()));
        return field != null
            && appView.appInfo().isStaticFieldWrittenOnlyInEnclosingStaticInitializer(field)
            && !appView.appInfo().isFieldRead(field);
      }
    }
    return false;
  }

  /**
   * Each EnumLiteMap subclass has only two virtual methods findValueByNumber:
   *
   * <ul>
   *   <li>EnumLite findValueByNumber(int)
   *   <li>ConcreteEnumLiteSubType findValueByNumber(int)
   * </ul>
   *
   * <p>The method with the EnumLite return type is the bridge, we extract the concrete EnumLite
   * subtype from the other method return type.
   *
   * <p>We bail out if other virtual methods than the two expected ones are found and return null.
   */
  private DexProgramClass computeCorrespondingEnumLite(DexProgramClass enumLiteMap) {
    if (enumLiteMap.getMethodCollection().numberOfVirtualMethods() != 2) {
      return null;
    }
    DexType enumLiteCandidate = null;
    for (DexEncodedMethod virtualMethod : enumLiteMap.virtualMethods()) {
      if (!matchesFindValueByNumberMethod(virtualMethod.getReference())) {
        return null;
      }
      if (virtualMethod.returnType() == references.enumLiteType) {
        continue;
      }
      if (enumLiteCandidate != null) {
        return null;
      }
      enumLiteCandidate = virtualMethod.returnType();
    }
    if (enumLiteCandidate == null) {
      return null;
    }
    DexProgramClass enumLite = appView.programDefinitionFor(enumLiteCandidate, enumLiteMap);
    if (enumLite != null
        && enumLite.isEnum()
        && enumLite.interfaces.contains(references.enumLiteType)) {
      return enumLite;
    }
    return null;
  }

  private boolean matchesFindValueByNumberMethod(DexMethod method) {
    return method.name == references.findValueByNumberName
        && method.getArity() == 1
        && method.getParameters().values[0] == appView.dexItemFactory().intType;
  }

  public void verifyDeadEnumLiteMapsAreDead() {
    for (DexType deadEnumLiteMap : deadEnumLiteMaps) {
      if (appView.appInfo().definitionForWithoutExistenceAssert(deadEnumLiteMap) != null) {
        throw new CompilationError(
            "EnumLite Proto Shrinker failure: Type "
                + deadEnumLiteMap
                + " was assumed to be dead during optimizations, but it is not.");
      }
    }
  }
}
