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

import com.android.tools.r8.graph.AbstractAccessContexts.ConcreteAccessContexts;
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.DexField;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.FieldAccessInfoCollection;
import com.android.tools.r8.graph.FieldAccessInfoCollectionImpl;
import com.android.tools.r8.graph.FieldAccessInfoImpl;
import com.android.tools.r8.graph.FieldResolutionResult.SuccessfulFieldResolutionResult;
import com.android.tools.r8.graph.MethodAccessInfoCollection;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.graph.ResolutionResult.SingleResolutionResult;
import com.android.tools.r8.graph.UseRegistry;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.utils.ThreadUtils;
import com.android.tools.r8.utils.collections.ProgramMethodSet;
import com.google.common.collect.Sets;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;

public class MemberRebindingIdentityLensFactory {

  /**
   * In order to construct an instance of {@link MemberRebindingIdentityLens} we need a mapping from
   * non-rebound field and method references to their definitions.
   *
   * <p>If shrinking or minification is enabled, we retrieve these from {@link AppInfoWithLiveness}.
   * Otherwise we apply the {@link NonReboundMemberReferencesRegistry} below to all code objects to
   * compute the mapping.
   */
  public static MemberRebindingIdentityLens create(
      AppView<? extends AppInfoWithClassHierarchy> appView, ExecutorService executorService)
      throws ExecutionException {
    FieldAccessInfoCollection<?> fieldAccessInfoCollection;
    MethodAccessInfoCollection methodAccessInfoCollection;
    if (appView.appInfo().hasLiveness()
        && appView.options().testing.alwaysUseExistingAccessInfoCollectionsInMemberRebinding) {
      AppInfoWithLiveness appInfo = appView.appInfo().withLiveness();
      fieldAccessInfoCollection = appInfo.getFieldAccessInfoCollection();
      methodAccessInfoCollection = appInfo.getMethodAccessInfoCollection();
    } else {
      FieldAccessInfoCollectionImpl mutableFieldAccessInfoCollection =
          new FieldAccessInfoCollectionImpl(new ConcurrentHashMap<>());
      MethodAccessInfoCollection.ConcurrentBuilder methodAccessInfoCollectionBuilder =
          MethodAccessInfoCollection.concurrentBuilder();
      initializeMemberAccessInfoCollectionsForMemberRebinding(
          appView,
          mutableFieldAccessInfoCollection,
          methodAccessInfoCollectionBuilder,
          executorService);
      fieldAccessInfoCollection = mutableFieldAccessInfoCollection;
      methodAccessInfoCollection = methodAccessInfoCollectionBuilder.build();
    }
    return create(appView, fieldAccessInfoCollection, methodAccessInfoCollection);
  }

  public static MemberRebindingIdentityLens create(
      AppView<? extends AppInfoWithClassHierarchy> appView,
      FieldAccessInfoCollection<?> fieldAccessInfoCollection,
      MethodAccessInfoCollection methodAccessInfoCollection) {
    MemberRebindingIdentityLens.Builder builder = MemberRebindingIdentityLens.builder(appView);
    fieldAccessInfoCollection.forEach(builder::recordNonReboundFieldAccesses);
    methodAccessInfoCollection.forEachMethodReference(builder::recordMethodAccess);
    return builder.build();
  }

  /**
   * Applies {@link NonReboundMemberReferencesRegistry} to all code objects to construct a mapping
   * from non-rebound field references to their definition.
   */
  private static void initializeMemberAccessInfoCollectionsForMemberRebinding(
      AppView<? extends AppInfoWithClassHierarchy> appView,
      FieldAccessInfoCollectionImpl fieldAccessInfoCollection,
      MethodAccessInfoCollection.ConcurrentBuilder methodAccessInfoCollectionBuilder,
      ExecutorService executorService)
      throws ExecutionException {
    Set<DexField> seenFieldReferences = Sets.newConcurrentHashSet();
    Set<DexMethod> seenMethodReferences = Sets.newConcurrentHashSet();
    ThreadUtils.processItems(
        appView.appInfo()::forEachMethod,
        method ->
            new NonReboundMemberReferencesRegistry(
                    appView,
                    method,
                    fieldAccessInfoCollection,
                    methodAccessInfoCollectionBuilder,
                    seenFieldReferences,
                    seenMethodReferences)
                .accept(method),
        executorService);
  }

  private static class NonReboundMemberReferencesRegistry extends UseRegistry {

    private final AppInfoWithClassHierarchy appInfo;
    private final ProgramMethod context;
    private final FieldAccessInfoCollectionImpl fieldAccessInfoCollection;
    private final MethodAccessInfoCollection.ConcurrentBuilder methodAccessInfoCollectionBuilder;
    private final Set<DexField> seenFieldReferences;
    private final Set<DexMethod> seenMethodReferences;

    public NonReboundMemberReferencesRegistry(
        AppView<? extends AppInfoWithClassHierarchy> appView,
        ProgramMethod context,
        FieldAccessInfoCollectionImpl fieldAccessInfoCollection,
        MethodAccessInfoCollection.ConcurrentBuilder methodAccessInfoCollectionBuilder,
        Set<DexField> seenFieldReferences,
        Set<DexMethod> seenMethodReferences) {
      super(appView.dexItemFactory());
      this.appInfo = appView.appInfo();
      this.context = context;
      this.fieldAccessInfoCollection = fieldAccessInfoCollection;
      this.methodAccessInfoCollectionBuilder = methodAccessInfoCollectionBuilder;
      this.seenFieldReferences = seenFieldReferences;
      this.seenMethodReferences = seenMethodReferences;
    }

    @Override
    public void registerInstanceFieldRead(DexField field) {
      registerFieldAccess(field);
    }

    @Override
    public void registerInstanceFieldWrite(DexField field) {
      registerFieldAccess(field);
    }

    @Override
    public void registerStaticFieldRead(DexField field) {
      registerFieldAccess(field);
    }

    @Override
    public void registerStaticFieldWrite(DexField field) {
      registerFieldAccess(field);
    }

    private void registerFieldAccess(DexField field) {
      if (!seenFieldReferences.add(field)) {
        return;
      }
      SuccessfulFieldResolutionResult resolutionResult =
          appInfo.resolveField(field).asSuccessfulResolution();
      if (resolutionResult == null) {
        return;
      }
      DexField reboundReference = resolutionResult.getResolvedField().toReference();
      if (field == reboundReference) {
        // For the purpose of member rebinding, we don't care about already rebound references.
        return;
      }
      FieldAccessInfoImpl fieldAccessInfo =
          fieldAccessInfoCollection.computeIfAbsent(reboundReference, FieldAccessInfoImpl::new);
      synchronized (fieldAccessInfo) {
        // Record the fact that there is a non-rebound access to the given field. We don't
        // distinguish between non-rebound reads and writes, so we just record it as a read.
        ConcreteAccessContexts accessContexts =
            fieldAccessInfo.getReadsWithContexts().isConcrete()
                ? fieldAccessInfo.getReadsWithContexts().asConcrete()
                : new ConcreteAccessContexts();
        // For the purpose of member rebinding, we don't care about the access contexts, so we
        // simply use the empty set.
        accessContexts.getAccessesWithContexts().put(field, ProgramMethodSet.empty());
      }
    }

    @Override
    public void registerInvokeDirect(DexMethod method) {
      registerInvokeMethod(method, methodAccessInfoCollectionBuilder.getDirectInvokes());
    }

    @Override
    public void registerInvokeInterface(DexMethod method) {
      registerInvokeMethod(method, methodAccessInfoCollectionBuilder.getInterfaceInvokes());
    }

    @Override
    public void registerInvokeStatic(DexMethod method) {
      registerInvokeMethod(method, methodAccessInfoCollectionBuilder.getStaticInvokes());
    }

    @Override
    public void registerInvokeSuper(DexMethod method) {
      registerInvokeMethod(method, methodAccessInfoCollectionBuilder.getSuperInvokes());
    }

    @Override
    public void registerInvokeVirtual(DexMethod method) {
      registerInvokeMethod(method, methodAccessInfoCollectionBuilder.getVirtualInvokes());
    }

    private void registerInvokeMethod(DexMethod method, Map<DexMethod, ProgramMethodSet> invokes) {
      if (!seenMethodReferences.add(method)) {
        return;
      }
      if (method.getHolderType().isArrayType()) {
        return;
      }
      DexClass holder = appInfo.definitionFor(method.getHolderType(), context);
      if (holder == null) {
        return;
      }
      SingleResolutionResult resolutionResult =
          appInfo.resolveMethodOn(holder, method).asSingleResolution();
      if (resolutionResult == null) {
        return;
      }
      DexMethod reboundReference = resolutionResult.getResolvedMethod().getReference();
      if (method == reboundReference) {
        // For the purpose of member rebinding, we don't care about already rebound references.
        return;
      }
      // For the purpose of member rebinding, we don't care about the access contexts, so we
      // simply use the empty set.
      invokes.put(method, ProgramMethodSet.empty());
    }

    @Override
    public void registerInitClass(DexType type) {
      // Intentionally empty.
    }

    @Override
    public void registerNewInstance(DexType type) {
      // Intentionally empty.
    }

    @Override
    public void registerTypeReference(DexType type) {
      // Intentionally empty.
    }

    @Override
    public void registerInstanceOf(DexType type) {
      // Intentionally empty.
    }
  }
}
