// 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.horizontalclassmerging.policies;

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.DexMethodSignature;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.graph.ResolutionResult.SingleResolutionResult;
import com.android.tools.r8.horizontalclassmerging.HorizontalClassMerger.Mode;
import com.android.tools.r8.horizontalclassmerging.MergeGroup;
import com.android.tools.r8.horizontalclassmerging.MultiClassPolicy;
import com.android.tools.r8.utils.IterableUtils;
import com.android.tools.r8.utils.SetUtils;
import com.google.common.collect.Iterables;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;

/**
 * Identifies when virtual method merging is required and bails out. This is needed to ensure that
 * we don't need to synthesize any $r8$classId fields, such that the result of the final round of
 * class merging can be described as a renaming only.
 */
public class NoVirtualMethodMerging extends MultiClassPolicy {

  private final AppView<? extends AppInfoWithClassHierarchy> appView;

  public NoVirtualMethodMerging(AppView<? extends AppInfoWithClassHierarchy> appView, Mode mode) {
    assert mode.isFinal();
    this.appView = appView;
  }

  @Override
  public Collection<MergeGroup> apply(MergeGroup group) {
    Map<MergeGroup, Map<DexMethodSignature, ProgramMethod>> newGroups = new LinkedHashMap<>();
    for (DexProgramClass clazz : group) {
      Map<DexMethodSignature, ProgramMethod> classMethods = new HashMap<>();
      clazz.forEachProgramVirtualMethodMatching(
          DexEncodedMethod::isNonAbstractVirtualMethod,
          method -> classMethods.put(method.getMethodSignature(), method));

      MergeGroup newGroup = null;
      for (Entry<MergeGroup, Map<DexMethodSignature, ProgramMethod>> entry : newGroups.entrySet()) {
        MergeGroup candidateGroup = entry.getKey();
        Map<DexMethodSignature, ProgramMethod> groupMethods = entry.getValue();
        if (canAddNonAbstractVirtualMethodsToGroup(
            clazz, classMethods.values(), candidateGroup, groupMethods)) {
          newGroup = candidateGroup;
          groupMethods.putAll(classMethods);
          break;
        }
      }

      if (newGroup != null) {
        newGroup.add(clazz);
      } else {
        newGroups.put(new MergeGroup(clazz), classMethods);
      }
    }
    return removeTrivialGroups(newGroups.keySet());
  }

  private boolean canAddNonAbstractVirtualMethodsToGroup(
      DexProgramClass clazz,
      Collection<ProgramMethod> methods,
      MergeGroup group,
      Map<DexMethodSignature, ProgramMethod> groupMethods) {
    // For each of clazz' virtual methods, check that adding these methods to the group does not
    // require method merging.
    for (ProgramMethod method : methods) {
      ProgramMethod groupMethod = groupMethods.get(method.getMethodSignature());
      if (groupMethod != null || hasNonAbstractDefinitionInHierarchy(group, method)) {
        return false;
      }
    }
    // For each of the group's virtual methods, check that adding these methods clazz does not
    // require method merging.
    for (ProgramMethod method : groupMethods.values()) {
      if (hasNonAbstractDefinitionInHierarchy(clazz, method)) {
        return false;
      }
    }
    return true;
  }

  private boolean hasNonAbstractDefinitionInHierarchy(MergeGroup group, ProgramMethod method) {
    return hasNonAbstractDefinitionInSuperClass(group.getSuperType(), method)
        || hasNonAbstractDefinitionInSuperInterface(
            SetUtils.newIdentityHashSet(IterableUtils.flatMap(group, DexClass::getInterfaces)),
            method);
  }

  private boolean hasNonAbstractDefinitionInHierarchy(DexProgramClass clazz, ProgramMethod method) {
    return hasNonAbstractDefinitionInSuperClass(clazz.getSuperType(), method)
        || hasNonAbstractDefinitionInSuperInterface(clazz.getInterfaces(), method);
  }

  private boolean hasNonAbstractDefinitionInSuperClass(DexType superType, ProgramMethod method) {
    SingleResolutionResult resolutionResult =
        appView
            .appInfo()
            .resolveMethodOnClass(method.getReference(), superType)
            .asSingleResolution();
    return resolutionResult != null && !resolutionResult.getResolvedMethod().isAbstract();
  }

  private boolean hasNonAbstractDefinitionInSuperInterface(
      Iterable<DexType> interfaceTypes, ProgramMethod method) {
    return Iterables.any(
        interfaceTypes,
        interfaceType -> {
          SingleResolutionResult resolutionResult =
              appView
                  .appInfo()
                  .resolveMethodOnInterface(interfaceType, method.getReference())
                  .asSingleResolution();
          return resolutionResult != null && !resolutionResult.getResolvedMethod().isAbstract();
        });
  }

  @Override
  public String getName() {
    return "NoVirtualMethodMerging";
  }
}
