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

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.DexItemFactory;
import com.android.tools.r8.graph.DexMember;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexProto;
import com.android.tools.r8.graph.DexReference;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.EnumValueInfoMapCollection.EnumValueInfoMap;
import com.android.tools.r8.ir.optimize.enums.EnumUnboxer.Reason;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.google.common.collect.Sets;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

class EnumUnboxingCandidateAnalysis {

  private final AppView<AppInfoWithLiveness> appView;
  private final EnumUnboxer enumUnboxer;
  private final DexItemFactory factory;
  private Map<DexType, Set<DexEncodedMethod>> enumToUnboxCandidates = new ConcurrentHashMap<>();

  EnumUnboxingCandidateAnalysis(AppView<AppInfoWithLiveness> appView, EnumUnboxer enumUnboxer) {
    this.appView = appView;
    this.enumUnboxer = enumUnboxer;
    factory = appView.dexItemFactory();
  }

  Map<DexType, Set<DexEncodedMethod>> findCandidates() {
    for (DexProgramClass clazz : appView.appInfo().classes()) {
      if (isEnumUnboxingCandidate(clazz)) {
        enumToUnboxCandidates.put(clazz.type, Sets.newConcurrentHashSet());
      }
    }
    removePinnedCandidates();
    return enumToUnboxCandidates;
  }

  private boolean isEnumUnboxingCandidate(DexProgramClass clazz) {
    if (!clazz.isEnum()) {
      return false;
    }
    if (!clazz.isEffectivelyFinal(appView)) {
      enumUnboxer.reportFailure(clazz.type, Reason.SUBTYPES);
      return false;
    }
    // TODO(b/147860220): interfaces without default methods should be acceptable if the build setup
    // is correct (all abstract methods are implemented).
    if (!clazz.interfaces.isEmpty()) {
      enumUnboxer.reportFailure(clazz.type, Reason.INTERFACE);
      return false;
    }
    if (!clazz.instanceFields().isEmpty()) {
      enumUnboxer.reportFailure(clazz.type, Reason.INSTANCE_FIELD);
      return false;
    }
    if (!enumHasBasicStaticFields(clazz)) {
      enumUnboxer.reportFailure(clazz.type, Reason.UNEXPECTED_STATIC_FIELD);
      return false;
    }
    if (!clazz.virtualMethods().isEmpty()) {
      enumUnboxer.reportFailure(clazz.type, Reason.VIRTUAL_METHOD);
      return false;
    }
    EnumValueInfoMap enumValueInfoMap =
        appView.appInfo().withLiveness().getEnumValueInfoMap(clazz.type);
    if (enumValueInfoMap == null) {
      enumUnboxer.reportFailure(clazz.type, Reason.MISSING_INFO_MAP);
      return false;
    }
    // Methods values, valueOf, init, clinit are present on each enum.
    // Methods init and clinit are required if the enum is used.
    // Methods valueOf and values are normally kept by the commonly used/recommended enum keep rule
    // -keepclassmembers,allowoptimization enum * {
    //     public static **[] values();
    //     public static ** valueOf(java.lang.String);
    // }
    // In general there will be 4 methods, unless the enum keep rule is not present.
    if (clazz.directMethods().size() > 4) {
      enumUnboxer.reportFailure(clazz.type, Reason.UNEXPECTED_DIRECT_METHOD);
      return false;
    }
    for (DexEncodedMethod directMethod : clazz.directMethods()) {
      if (!(factory.enumMethods.isValuesMethod(directMethod.method, clazz)
          || factory.enumMethods.isValueOfMethod(directMethod.method, clazz)
          || isStandardEnumInitializer(directMethod)
          || directMethod.isClassInitializer())) {
        enumUnboxer.reportFailure(clazz.type, Reason.UNEXPECTED_DIRECT_METHOD);
        return false;
      }
    }
    return true;
  }

  private boolean isStandardEnumInitializer(DexEncodedMethod method) {
    return method.isInstanceInitializer()
        && method.method.proto == factory.enumMethods.constructor.proto;
  }

  // The enum should have the $VALUES static field and only fields directly referencing the enum
  // instances.
  private boolean enumHasBasicStaticFields(DexProgramClass clazz) {
    for (DexEncodedField staticField : clazz.staticFields()) {
      if (staticField.field.type == clazz.type
          && staticField.accessFlags.isEnum()
          && staticField.accessFlags.isFinal()) {
        // Enum field, valid, do nothing.
      } else if (staticField.field.type.isArrayType()
          && staticField.field.type.toArrayElementType(factory) == clazz.type
          && staticField.accessFlags.isSynthetic()
          && staticField.accessFlags.isFinal()
          && staticField.field.name == factory.enumValuesFieldName) {
        // Field $VALUES, valid, do nothing.
      } else {
        return false;
      }
    }
    return true;
  }

  private void removePinnedCandidates() {
    // A holder type, for field or method, should block enum unboxing only if the enum type is
    // also kept. This is to allow the keep rule -keepclassmembers to be used on enums while
    // enum unboxing can still be performed.
    for (DexReference item : appView.appInfo().getPinnedItems()) {
      if (item.isDexType()) {
        removePinnedCandidate(item.asDexType());
      } else if (item.isDexField()) {
        DexField field = item.asDexField();
        removePinnedIfNotHolder(field, field.type);
      } else {
        assert item.isDexMethod();
        DexMethod method = item.asDexMethod();
        DexProto proto = method.proto;
        removePinnedIfNotHolder(method, proto.returnType);
        for (DexType parameterType : proto.parameters.values) {
          removePinnedIfNotHolder(method, parameterType);
        }
      }
    }
  }

  private void removePinnedIfNotHolder(DexMember<?, ?> member, DexType type) {
    if (type != member.holder) {
      removePinnedCandidate(type);
    }
  }

  private void removePinnedCandidate(DexType type) {
    if (enumToUnboxCandidates.containsKey(type)) {
      enumUnboxer.reportFailure(type, Reason.PINNED);
      enumToUnboxCandidates.remove(type);
    }
  }
}
