// Copyright (c) 2021, 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.utils;

import static com.android.tools.r8.graph.DexLibraryClass.asLibraryClassOrNull;

import com.android.tools.r8.androidapi.AndroidApiLevelCompute;
import com.android.tools.r8.androidapi.ComputedApiLevel;
import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexEncodedMethod;
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.DexType;
import com.android.tools.r8.graph.LibraryClass;
import com.android.tools.r8.graph.LibraryDefinition;
import com.android.tools.r8.graph.LibraryMethod;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.optimize.inliner.NopWhyAreYouNotInliningReporter;
import com.android.tools.r8.ir.optimize.inliner.WhyAreYouNotInliningReporter;
import com.google.common.collect.Sets;
import java.util.Collections;
import java.util.Set;

public class AndroidApiLevelUtils {

  public static boolean isApiSafeForInlining(
      ProgramMethod caller, ProgramMethod inlinee, InternalOptions options) {
    return isApiSafeForInlining(
        caller, inlinee, options, NopWhyAreYouNotInliningReporter.getInstance());
  }

  @SuppressWarnings("ReferenceEquality")
  public static boolean isApiSafeForInlining(
      ProgramMethod caller,
      ProgramMethod inlinee,
      InternalOptions options,
      WhyAreYouNotInliningReporter whyAreYouNotInliningReporter) {
    if (!options.apiModelingOptions().isApiCallerIdentificationEnabled()) {
      return true;
    }
    if (caller.getHolderType() == inlinee.getHolderType()) {
      return true;
    }
    ComputedApiLevel callerApiLevelForCode = caller.getDefinition().getApiLevelForCode();
    if (callerApiLevelForCode.isUnknownApiLevel()) {
      whyAreYouNotInliningReporter.reportCallerHasUnknownApiLevel();
      return false;
    }
    // For inlining we only measure if the code has invokes into the library.
    ComputedApiLevel inlineeApiLevelForCode = inlinee.getDefinition().getApiLevelForCode();
    if (!caller
        .getDefinition()
        .getApiLevelForCode()
        .isGreaterThanOrEqualTo(inlineeApiLevelForCode)) {
      whyAreYouNotInliningReporter.reportInlineeHigherApiCall(
          callerApiLevelForCode, inlineeApiLevelForCode);
      return false;
    }
    return true;
  }

  public static ComputedApiLevel getApiReferenceLevelForMerging(
      AndroidApiLevelCompute apiLevelCompute, DexProgramClass clazz) {
    // The api level of a class is the max level of it's members, super class and interfaces.
    return getMembersApiReferenceLevelForMerging(
        clazz, apiLevelCompute.computeApiLevelForDefinition(clazz.allImmediateSupertypes()));
  }

  public static ComputedApiLevel getMembersApiReferenceLevelForMerging(
      DexProgramClass clazz, ComputedApiLevel memberLevel) {
    // Based on b/138781768#comment57 there is almost no penalty for having an unknown reference
    // as long as we are not invoking or accessing a field on it. Therefore we can disregard static
    // types of fields and only consider method code api levels.
    for (DexEncodedMethod method : clazz.methods()) {
      if (method.hasCode()) {
        ComputedApiLevel apiLevelForCode = method.getApiLevelForCode();
        if (apiLevelForCode.isNotSetApiLevel()) {
          return ComputedApiLevel.notSet();
        }
        memberLevel = memberLevel.max(apiLevelForCode);
      }
      if (memberLevel.isUnknownApiLevel()) {
        return memberLevel;
      }
    }
    return memberLevel;
  }

  public static boolean isApiSafeForMemberRebinding(
      LibraryMethod method,
      DexMethod original,
      AndroidApiLevelCompute androidApiLevelCompute,
      InternalOptions options) {
    if (!androidApiLevelCompute.isEnabled()) {
      assert !options.apiModelingOptions().enableLibraryApiModeling;
      return false;
    }
    assert options.apiModelingOptions().enableLibraryApiModeling;
    ComputedApiLevel apiLevel =
        androidApiLevelCompute.computeApiLevelForLibraryReference(
            method.getReference(), ComputedApiLevel.unknown());
    if (apiLevel.isUnknownApiLevel()) {
      return false;
    }
    ComputedApiLevel apiLevelOfOriginal =
        androidApiLevelCompute.computeApiLevelForLibraryReference(
            original, ComputedApiLevel.unknown());
    if (apiLevelOfOriginal.isUnknownApiLevel()) {
      return false;
    }
    return apiLevelOfOriginal.max(apiLevel).isLessThanOrEqualTo(options.getMinApiLevel()).isTrue();
  }

  public static boolean isApiSafeForReference(DexType type, AppView<?> appView) {
    DexItemFactory dexItemFactory = appView.dexItemFactory();
    DexType baseType = type.toBaseType(dexItemFactory);
    if (baseType.isPrimitiveType()) {
      return true;
    }
    DexClass baseClass = appView.definitionFor(baseType);
    if (baseClass == null) {
      // This could be a library class that is only available on newer api levels.
      return false;
    }
    if (!baseClass.isLibraryClass()) {
      // Program and classpath classes are not api level dependent.
      return true;
    }
    LibraryClass baseLibraryClass = baseClass.asLibraryClass();
    return isApiSafeForReference(baseLibraryClass, appView);
  }

  public static boolean isApiSafeForReference(LibraryDefinition definition, AppView<?> appView) {
    return isApiSafeForReference(
        definition, appView.apiLevelCompute(), appView.options(), appView.dexItemFactory());
  }

  @SuppressWarnings("ReferenceEquality")
  private static boolean isApiSafeForReference(
      LibraryDefinition definition,
      AndroidApiLevelCompute androidApiLevelCompute,
      InternalOptions options,
      DexItemFactory factory) {
    if (!options.apiModelingOptions().isApiLibraryModelingEnabled()) {
      return factory.libraryTypesAssumedToBePresent.contains(definition.getContextType());
    }
    ComputedApiLevel apiLevel =
        androidApiLevelCompute.computeApiLevelForLibraryReference(
            definition.getReference(), ComputedApiLevel.unknown());
    return apiLevel.isLessThanOrEqualTo(options.getMinApiLevel()).isTrue();
  }

  private static boolean isApiSafeForReference(
      LibraryDefinition newDefinition, LibraryDefinition oldDefinition, AppView<?> appView) {
    assert appView.options().apiModelingOptions().isApiLibraryModelingEnabled();
    assert !isApiSafeForReference(newDefinition, appView)
        : "Clients should first check if the definition is present on all apis since the min api";
    AndroidApiLevelCompute androidApiLevelCompute = appView.apiLevelCompute();
    ComputedApiLevel apiLevel =
        androidApiLevelCompute.computeApiLevelForLibraryReference(
            newDefinition.getReference(), ComputedApiLevel.unknown());
    if (apiLevel.isUnknownApiLevel()) {
      return false;
    }
    ComputedApiLevel apiLevelOfOriginal =
        androidApiLevelCompute.computeApiLevelForLibraryReference(
            oldDefinition.getReference(), ComputedApiLevel.unknown());
    return apiLevel.isLessThanOrEqualTo(apiLevelOfOriginal).isTrue();
  }

  @SuppressWarnings({"MixedMutabilityReturnType", "ReferenceEquality"})
  public static boolean isApiSafeForTypeStrengthening(
      DexType newType, DexType oldType, AppView<? extends AppInfoWithClassHierarchy> appView) {
    // Type strengthening only applies to reference types.
    assert newType.isReferenceType();
    assert oldType.isReferenceType();
    assert newType != oldType;
    DexItemFactory dexItemFactory = appView.dexItemFactory();
    DexType newBaseType = newType.toBaseType(dexItemFactory);
    if (newBaseType.isPrimitiveType()) {
      // Array of primitives is available on all api levels.
      return true;
    }
    assert newBaseType.isClassType();
    DexClass newBaseClass = appView.definitionFor(newBaseType);
    if (newBaseClass == null) {
      // This could be a library class that is only available on newer api levels.
      return false;
    }
    if (!newBaseClass.isLibraryClass()) {
      // Program and classpath classes are not api level dependent.
      return true;
    }
    if (!appView.options().apiModelingOptions().isApiLibraryModelingEnabled()) {
      // Conservatively bail out if we don't have api modeling.
      return false;
    }
    LibraryClass newBaseLibraryClass = newBaseClass.asLibraryClass();
    if (isApiSafeForReference(newBaseLibraryClass, appView)) {
      // Library class is present on all api levels since min api.
      return true;
    }
    // Check if the new library class is present since the api level of the old type.
    DexType oldBaseType = oldType.toBaseType(dexItemFactory);
    assert oldBaseType.isClassType();
    LibraryClass oldBaseLibraryClass = asLibraryClassOrNull(appView.definitionFor(oldBaseType));
    return oldBaseLibraryClass != null
        && isApiSafeForReference(newBaseLibraryClass, oldBaseLibraryClass, appView);
  }

  public static Pair<DexClass, ComputedApiLevel> findAndComputeApiLevelForLibraryDefinition(
      AppView<?> appView,
      AppInfoWithClassHierarchy appInfo,
      DexClass holder,
      DexMember<?, ?> reference) {
    AndroidApiLevelCompute apiLevelCompute = appView.apiLevelCompute();
    if (holder.isLibraryClass()) {
      return Pair.create(
          holder,
          apiLevelCompute.computeApiLevelForLibraryReference(
              reference, ComputedApiLevel.unknown()));
    }
    // The API database do not allow for resolving into it (since that is not stable), and it is
    // therefore designed in a way where all members of classes can be queried on any sub-type with
    // the api level for where it is reachable. It is therefore sufficient for us, to figure out if
    // an instruction is a library call, to either find a program definition or to find the library
    // frontier.
    // Scan through the type hierarchy to find the first library class or program definition.
    DexClass firstClassWithReferenceOrLibraryClass =
        firstLibraryClassOrProgramClassWithDefinition(appInfo, holder, reference);
    if (firstClassWithReferenceOrLibraryClass == null) {
      return Pair.create(null, ComputedApiLevel.unknown());
    }
    if (!firstClassWithReferenceOrLibraryClass.isLibraryClass()) {
      return Pair.create(firstClassWithReferenceOrLibraryClass, appView.computedMinApiLevel());
    }
    ComputedApiLevel apiLevel =
        apiLevelCompute.computeApiLevelForLibraryReference(
            reference.withHolder(
                firstClassWithReferenceOrLibraryClass.getType(), appView.dexItemFactory()),
            ComputedApiLevel.unknown());
    if (apiLevel.isKnownApiLevel()) {
      return Pair.create(firstClassWithReferenceOrLibraryClass, apiLevel);
    }
    // We were unable to find a definition in the class hierarchy, check all interfaces for a
    // definition or the library interfaces for the first interface definition.
    Set<DexClass> firstLibraryInterfaces =
        findAllFirstLibraryInterfacesOrProgramClassWithDefinition(appInfo, holder, reference);
    if (firstLibraryInterfaces.size() == 1) {
      DexClass firstClass = firstLibraryInterfaces.iterator().next();
      if (!firstClass.isLibraryClass()) {
        return Pair.create(firstClass, appView.computedMinApiLevel());
      }
    }
    DexClass foundClass = null;
    ComputedApiLevel minApiLevel = ComputedApiLevel.unknown();
    for (DexClass libraryInterface : firstLibraryInterfaces) {
      assert libraryInterface.isLibraryClass();
      ComputedApiLevel libraryIfaceApiLevel =
          apiLevelCompute.computeApiLevelForLibraryReference(
              reference.withHolder(
                  firstClassWithReferenceOrLibraryClass.getType(), appView.dexItemFactory()),
              ComputedApiLevel.unknown());
      if (minApiLevel.isGreaterThan(libraryIfaceApiLevel)) {
        minApiLevel = libraryIfaceApiLevel;
        foundClass = libraryInterface;
      }
    }
    return Pair.create(foundClass, minApiLevel);
  }

  private static DexClass firstLibraryClassOrProgramClassWithDefinition(
      AppInfoWithClassHierarchy appInfo, DexClass originalClass, DexMember<?, ?> reference) {
    if (originalClass.isLibraryClass()) {
      return originalClass;
    }
    return WorkList.newIdentityWorkList(originalClass)
        .run(
            (clazz, workList) -> {
              if (clazz.isLibraryClass()) {
                return TraversalContinuation.doBreak(clazz);
              } else if (clazz.lookupMember(reference) != null) {
                return TraversalContinuation.doBreak(clazz);
              } else if (clazz.getSuperType() != null) {
                appInfo
                    .contextIndependentDefinitionForWithResolutionResult(clazz.getSuperType())
                    .forEachClassResolutionResult(workList::addIfNotSeen);
              }
              return TraversalContinuation.doContinue();
            })
        .asBreakOrDefault(null)
        .getValue();
  }

  @SuppressWarnings("MixedMutabilityReturnType")
  private static Set<DexClass> findAllFirstLibraryInterfacesOrProgramClassWithDefinition(
      AppInfoWithClassHierarchy appInfo, DexClass originalClass, DexMember<?, ?> reference) {
    Set<DexClass> interfaces = Sets.newLinkedHashSet();
    WorkList<DexClass> workList = WorkList.newIdentityWorkList(originalClass);
    while (workList.hasNext()) {
      DexClass clazz = workList.next();
      if (clazz.isLibraryClass()) {
        if (clazz.isInterface()) {
          interfaces.add(clazz);
        }
      } else if (clazz.lookupMember(reference) != null) {
        return Collections.singleton(clazz);
      } else {
        clazz.forEachImmediateSupertype(
            superType ->
                appInfo
                    .contextIndependentDefinitionForWithResolutionResult(superType)
                    .forEachClassResolutionResult(workList::addIfNotSeen));
      }
    }
    return interfaces;
  }

  /**
   * A lot of functionality has already been outlined in androidx. The ordinary pattern for manual
   * outlining is to create a class with the name ApiXXImpl where XX is the api level. This method
   * will check the context to see if it matches this pattern in androidx and extract the api level
   * for comparison with the computed api level.
   */
  public static boolean isOutlinedAtSameOrLowerLevel(
      DexProgramClass clazz, ComputedApiLevel apiLevel) {
    assert apiLevel.isKnownApiLevel();
    if (!clazz.getType().getDescriptor().startsWith("Landroidx/")) {
      return false;
    }
    String simpleName = clazz.getSimpleName();
    int apiIndex = simpleName.indexOf("Api");
    if (apiIndex < 0) {
      return false;
    }
    int endApiIndex = apiIndex += 3;
    int implIndex = simpleName.indexOf("Impl");
    if (implIndex < 0 || implIndex < endApiIndex || (implIndex - endApiIndex) != 2) {
      return false;
    }
    String apiLevelAsString = simpleName.substring(endApiIndex, implIndex);
    if (!StringUtils.onlyContainsDigits(apiLevelAsString)) {
      return false;
    }
    int apiLevelAsInt = Integer.parseInt(apiLevelAsString);
    if (apiLevelAsInt < 10 || apiLevelAsInt > AndroidApiLevel.LATEST.getLevel()) {
      return false;
    }
    return apiLevel.asKnownApiLevel().getApiLevel().getLevel() <= apiLevelAsInt;
  }

  public static boolean isApiLevelLessThanOrEqualToG(ComputedApiLevel apiLevel) {
    return apiLevel.isKnownApiLevel()
        && apiLevel.asKnownApiLevel().getApiLevel().isLessThanOrEqualTo(AndroidApiLevel.G);
  }
}
