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

import com.android.tools.r8.dex.Constants;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexAnnotationSet;
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.DexMethod;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexProto;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.FieldAccessFlags;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.shaking.FieldAccessInfoCollectionModifier;
import com.android.tools.r8.utils.MethodSignatureEquivalence;
import com.google.common.base.Equivalence.Wrapper;
import com.google.common.collect.Iterables;
import it.unimi.dsi.fastutil.objects.Reference2IntMap;
import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.IdentityHashMap;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * The class merger is responsible for moving methods from {@link ClassMerger#toMergeGroup} into the
 * class {@link ClassMerger#target}. While performing merging, this class tracks which methods have
 * been moved, as well as which fields have been remapped in the {@link ClassMerger#lensBuilder}.
 */
public class ClassMerger {
  public static final String CLASS_ID_FIELD_NAME = "$r8$classId";

  private final AppView<AppInfoWithLiveness> appView;
  private final DexProgramClass target;
  private final Collection<DexProgramClass> toMergeGroup;
  private final DexItemFactory dexItemFactory;
  private final HorizontalClassMergerGraphLens.Builder lensBuilder;
  private final FieldAccessInfoCollectionModifier.Builder fieldAccessChangesBuilder;

  private final Reference2IntMap<DexType> classIdentifiers = new Reference2IntOpenHashMap<>();
  private final Collection<VirtualMethodMerger> virtualMethodMergers;
  private final Collection<ConstructorMerger> constructorMergers;
  private final DexField classIdField;

  private ClassMerger(
      AppView<AppInfoWithLiveness> appView,
      HorizontalClassMergerGraphLens.Builder lensBuilder,
      FieldAccessInfoCollectionModifier.Builder fieldAccessChangesBuilder,
      DexProgramClass target,
      Collection<DexProgramClass> toMergeGroup,
      DexField classIdField,
      Collection<VirtualMethodMerger> virtualMethodMergers,
      Collection<ConstructorMerger> constructorMergers) {
    this.appView = appView;
    this.lensBuilder = lensBuilder;
    this.fieldAccessChangesBuilder = fieldAccessChangesBuilder;
    this.target = target;
    this.toMergeGroup = toMergeGroup;
    this.classIdField = classIdField;
    this.virtualMethodMergers = virtualMethodMergers;
    this.constructorMergers = constructorMergers;

    this.dexItemFactory = appView.dexItemFactory();

    buildClassIdentifierMap();
  }

  /** Returns an iterable over all classes that should be merged into the target class. */
  public Iterable<DexProgramClass> getToMergeClasses() {
    return toMergeGroup;
  }

  /**
   * Returns an iterable over both the target class as well as all classes that should be merged
   * into the target class.
   */
  public Iterable<DexProgramClass> getClasses() {
    return Iterables.concat(Collections.singleton(target), getToMergeClasses());
  }

  void buildClassIdentifierMap() {
    classIdentifiers.put(target.type, 0);
    for (DexProgramClass toMerge : toMergeGroup) {
      classIdentifiers.put(toMerge.type, classIdentifiers.size());
    }
  }

  void merge(DexProgramClass toMerge) {
    toMerge.forEachProgramDirectMethod(
        method -> {
          DexEncodedMethod definition = method.getDefinition();
          assert !definition.isClassInitializer();

          if (!definition.isInstanceInitializer()) {
            DexMethod newMethod = renameMethod(method);
            // TODO(b/165000217): Add all methods to `target` in one go using addDirectMethods().
            target.addDirectMethod(definition.toTypeSubstitutedMethod(newMethod));
            lensBuilder.moveMethod(definition.getReference(), newMethod);
          }
        });

    // Clear the members of the class to be merged since they have now been moved to the target.
    toMerge.setVirtualMethods(null);
    toMerge.setDirectMethods(null);
    toMerge.setInstanceFields(null);
    toMerge.setStaticFields(null);
  }

  /**
   * Find a new name for the method.
   *
   * @param method The class the method originally belonged to.
   */
  DexMethod renameMethod(ProgramMethod method) {
    return dexItemFactory.createFreshMethodName(
        method.getDefinition().method.name.toSourceString(),
        method.getHolderType(),
        method.getDefinition().proto(),
        target.type,
        tryMethod -> target.lookupMethod(tryMethod) == null);
  }

  void mergeConstructors(SyntheticArgumentClass syntheticArgumentClass) {
    for (ConstructorMerger merger : constructorMergers) {
      merger.merge(
          lensBuilder, fieldAccessChangesBuilder, classIdentifiers, syntheticArgumentClass);
    }
  }

  void mergeVirtualMethods() {
    for (VirtualMethodMerger merger : virtualMethodMergers) {
      merger.merge(lensBuilder, fieldAccessChangesBuilder, classIdentifiers);
    }
  }

  void appendClassIdField() {
    DexEncodedField encodedField =
        new DexEncodedField(
            classIdField,
            FieldAccessFlags.fromSharedAccessFlags(
                Constants.ACC_PUBLIC + Constants.ACC_FINAL + Constants.ACC_SYNTHETIC),
            DexAnnotationSet.empty(),
            null);
    target.appendInstanceField(encodedField);
  }

  public void mergeGroup(SyntheticArgumentClass syntheticArgumentClass) {
    appendClassIdField();

    for (DexProgramClass clazz : toMergeGroup) {
      merge(clazz);
      lensBuilder.mapType(clazz.type, target.type);
    }

    mergeConstructors(syntheticArgumentClass);
    mergeVirtualMethods();
  }

  public static class Builder {
    private final DexProgramClass target;
    private final Collection<DexProgramClass> toMergeGroup = new ArrayList<>();
    private final Map<DexProto, ConstructorMerger.Builder> constructorMergerBuilders =
        new IdentityHashMap<>();
    private final Map<Wrapper<DexMethod>, VirtualMethodMerger.Builder> virtualMethodMergerBuilders =
        new LinkedHashMap<>();

    public Builder(DexProgramClass target) {
      this.target = target;
      setupForMethodMerging(target);
    }

    public Builder mergeClass(DexProgramClass toMerge) {
      setupForMethodMerging(toMerge);
      toMergeGroup.add(toMerge);
      return this;
    }

    public Builder addClassesToMerge(Collection<DexProgramClass> toMerge) {
      toMerge.forEach(this::mergeClass);
      return this;
    }

    void setupForMethodMerging(DexProgramClass toMerge) {
      toMerge.forEachProgramDirectMethod(
          method -> {
            DexEncodedMethod definition = method.getDefinition();
            assert !definition.isClassInitializer();

            if (definition.isInstanceInitializer()) {
              addConstructor(method);
            }
          });

      toMerge.forEachProgramVirtualMethod(this::addVirtualMethod);
    }

    void addConstructor(ProgramMethod method) {
      assert method.getDefinition().isInstanceInitializer();
      constructorMergerBuilders
          .computeIfAbsent(
              method.getDefinition().getProto(), ignore -> new ConstructorMerger.Builder())
          .add(method.getDefinition());
    }

    void addVirtualMethod(ProgramMethod method) {
      assert method.getDefinition().isNonPrivateVirtualMethod();
      virtualMethodMergerBuilders
          .computeIfAbsent(
              MethodSignatureEquivalence.get().wrap(method.getReference()),
              ignore -> new VirtualMethodMerger.Builder())
          .add(method);
    }

    public ClassMerger build(
        AppView<AppInfoWithLiveness> appView,
        HorizontalClassMergerGraphLens.Builder lensBuilder,
        FieldAccessInfoCollectionModifier.Builder fieldAccessChangesBuilder) {
      DexItemFactory dexItemFactory = appView.dexItemFactory();
      // TODO(b/165498187): ensure the name for the field is fresh
      DexField classIdField =
          dexItemFactory.createField(target.type, dexItemFactory.intType, CLASS_ID_FIELD_NAME);

      Collection<VirtualMethodMerger> virtualMethodMergers =
          new ArrayList<>(virtualMethodMergerBuilders.size());
      for (VirtualMethodMerger.Builder builder : virtualMethodMergerBuilders.values()) {
        virtualMethodMergers.add(builder.build(appView, target, classIdField));
      }

      Collection<ConstructorMerger> constructorMergers =
          new ArrayList<>(constructorMergerBuilders.size());
      for (ConstructorMerger.Builder builder : constructorMergerBuilders.values()) {
        constructorMergers.add(builder.build(appView, target, classIdField));
      }

      return new ClassMerger(
          appView,
          lensBuilder,
          fieldAccessChangesBuilder,
          target,
          toMergeGroup,
          classIdField,
          virtualMethodMergers,
          constructorMergers);
    }
  }
}
