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

import static com.android.tools.r8.ir.analysis.type.Nullability.maybeNull;

import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexItemFactory.EnumMembers;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.analysis.value.AbstractValueFactory;
import com.android.tools.r8.ir.analysis.value.ObjectState;
import com.android.tools.r8.ir.optimize.info.LibraryOptimizationInfoInitializerFeedback;
import com.android.tools.r8.ir.optimize.info.field.EmptyInstanceFieldInitializationInfoCollection;
import com.android.tools.r8.ir.optimize.info.field.InstanceFieldInitializationInfoCollection;
import com.android.tools.r8.ir.optimize.info.field.InstanceFieldInitializationInfoFactory;
import com.android.tools.r8.ir.optimize.info.initializer.InstanceInitializerInfoCollection;
import com.android.tools.r8.ir.optimize.info.initializer.NonTrivialInstanceInitializerInfo;
import com.google.common.collect.Sets;
import java.util.BitSet;
import java.util.Set;

public class LibraryOptimizationInfoInitializer {

  private final AbstractValueFactory abstractValueFactory;
  private final AppView<?> appView;
  private final DexItemFactory dexItemFactory;

  private final LibraryOptimizationInfoInitializerFeedback feedback =
      LibraryOptimizationInfoInitializerFeedback.getInstance();
  private final Set<DexType> modeledLibraryTypes = Sets.newIdentityHashSet();

  LibraryOptimizationInfoInitializer(AppView<?> appView) {
    this.abstractValueFactory = appView.abstractValueFactory();
    this.appView = appView;
    this.dexItemFactory = appView.dexItemFactory();
  }

  void run(Set<DexEncodedField> finalLibraryFields) {
    modelInstanceInitializers();
    modelStaticFinalLibraryFields(finalLibraryFields);
    modelLibraryMethodsNonNullParamOrThrow();
    modelLibraryMethodsReturningNonNull();
    modelLibraryMethodsReturningReceiver();
    modelLibraryMethodsWithoutSideEffects();
    modelRequireNonNullMethods();
  }

  Set<DexType> getModeledLibraryTypes() {
    return modeledLibraryTypes;
  }

  private void modelInstanceInitializers() {
    DexEncodedMethod objectConstructor = lookupMethod(dexItemFactory.objectMembers.constructor);
    if (objectConstructor != null) {
      InstanceFieldInitializationInfoCollection fieldInitializationInfos =
          EmptyInstanceFieldInitializationInfoCollection.getInstance();
      feedback.setInstanceInitializerInfoCollection(
          objectConstructor,
          InstanceInitializerInfoCollection.of(
              NonTrivialInstanceInitializerInfo.builder(fieldInitializationInfos).build()));
    }

    EnumMembers enumMembers = dexItemFactory.enumMembers;
    DexEncodedMethod enumConstructor = lookupMethod(enumMembers.constructor);
    if (enumConstructor != null) {
      LibraryFieldSynthesis.synthesizeEnumFields(appView);
      InstanceFieldInitializationInfoFactory factory =
          appView.instanceFieldInitializationInfoFactory();
      InstanceFieldInitializationInfoCollection fieldInitializationInfos =
          InstanceFieldInitializationInfoCollection.builder()
              .recordInitializationInfo(
                  enumMembers.nameField, factory.createArgumentInitializationInfo(1))
              .recordInitializationInfo(
                  enumMembers.ordinalField, factory.createArgumentInitializationInfo(2))
              .build();
      feedback.setInstanceInitializerInfoCollection(
          enumConstructor,
          InstanceInitializerInfoCollection.of(
              NonTrivialInstanceInitializerInfo.builder(fieldInitializationInfos)
                  .setParent(dexItemFactory.objectMembers.constructor)
                  .build()));
    }
  }

  private void modelStaticFinalLibraryFields(Set<DexEncodedField> finalLibraryFields) {
    for (DexEncodedField field : finalLibraryFields) {
      if (field.isStatic()) {
        feedback.recordLibraryFieldHasAbstractValue(
            field,
            abstractValueFactory.createSingleFieldValue(field.getReference(), ObjectState.empty()));
      }
    }
  }

  private void modelLibraryMethodsNonNullParamOrThrow() {
    dexItemFactory.libraryMethodsNonNullParamOrThrow.forEach(
        (method, nonNullParamOrThrow) -> {
          DexEncodedMethod definition = lookupMethod(method);
          if (definition != null) {
            assert nonNullParamOrThrow.length > 0;
            int size = nonNullParamOrThrow[nonNullParamOrThrow.length - 1] + 1;
            BitSet bitSet = new BitSet(size);
            for (int argumentIndex : nonNullParamOrThrow) {
              assert argumentIndex < size;
              bitSet.set(argumentIndex);
            }
            feedback.setNonNullParamOrThrow(definition, bitSet);

            // Also set non-null-param-on-normal-exits info.
            if (definition.getOptimizationInfo().hasNonNullParamOnNormalExits()) {
              definition.getOptimizationInfo().getNonNullParamOnNormalExits().or(bitSet);
            } else {
              feedback.setNonNullParamOnNormalExits(definition, (BitSet) bitSet.clone());
            }
          }
        });
  }

  private void modelLibraryMethodsReturningNonNull() {
    for (DexMethod method : dexItemFactory.libraryMethodsReturningNonNull) {
      DexEncodedMethod definition = lookupMethod(method);
      if (definition != null) {
        TypeElement staticType =
            TypeElement.fromDexType(method.proto.returnType, maybeNull(), appView);
        feedback.methodReturnsObjectWithUpperBoundType(
            definition,
            appView,
            definition
                .getOptimizationInfo()
                .getDynamicUpperBoundTypeOrElse(staticType)
                .asReferenceType()
                .asDefinitelyNotNull());
      }
    }
  }

  private void modelLibraryMethodsReturningReceiver() {
    for (DexMethod method : dexItemFactory.libraryMethodsReturningReceiver) {
      DexEncodedMethod definition = lookupMethod(method);
      if (definition != null) {
        feedback.methodReturnsArgument(definition, 0);
      }
    }
  }

  private void modelLibraryMethodsWithoutSideEffects() {
    appView
        .getLibraryMethodSideEffectModelCollection()
        .forEachSideEffectFreeFinalMethod(
            method -> {
              DexEncodedMethod definition = lookupMethod(method);
              if (definition != null) {
                feedback.methodMayNotHaveSideEffects(definition);
              }
            });
  }

  private void modelRequireNonNullMethods() {
    for (DexMethod requireNonNullMethod : dexItemFactory.objectsMethods.requireNonNullMethods()) {
      DexEncodedMethod definition = lookupMethod(requireNonNullMethod);
      if (definition != null) {
        feedback.methodReturnsArgument(definition, 0);
      }
    }
  }

  private DexEncodedMethod lookupMethod(DexMethod method) {
    DexClass holder = appView.definitionForHolder(method);
    DexEncodedMethod definition = method.lookupOnClass(holder);
    if (definition != null) {
      modeledLibraryTypes.add(method.holder);
      return definition;
    }
    return null;
  }
}
