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

import static com.android.tools.r8.graph.DexProgramClass.asProgramClassOrNull;
import static com.android.tools.r8.utils.MapUtils.ignoreKey;

import com.android.tools.r8.graph.DexDefinitionSupplier;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexReference;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.ProgramDefinition;
import com.android.tools.r8.graph.ProgramField;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.graph.PrunedItems;
import com.android.tools.r8.shaking.KeepInfo.Joiner;
import com.android.tools.r8.utils.MapUtils;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiConsumer;
import java.util.function.BiPredicate;
import java.util.function.Predicate;

public class MinimumKeepInfoCollection {

  private static final MinimumKeepInfoCollection EMPTY =
      new MinimumKeepInfoCollection(Collections.emptyMap());

  private final Map<DexReference, KeepInfo.Joiner<?, ?, ?>> minimumKeepInfo;

  public MinimumKeepInfoCollection() {
    this(new ConcurrentHashMap<>());
  }

  private MinimumKeepInfoCollection(Map<DexReference, KeepInfo.Joiner<?, ?, ?>> minimumKeepInfo) {
    this.minimumKeepInfo = minimumKeepInfo;
  }

  public static MinimumKeepInfoCollection empty() {
    return EMPTY;
  }

  public void forEach(BiConsumer<DexReference, KeepInfo.Joiner<?, ?, ?>> consumer) {
    minimumKeepInfo.forEach(consumer);
  }

  public void forEach(
      DexDefinitionSupplier definitions,
      BiConsumer<DexProgramClass, KeepClassInfo.Joiner> classConsumer,
      BiConsumer<ProgramField, KeepFieldInfo.Joiner> fieldConsumer,
      BiConsumer<ProgramMethod, KeepMethodInfo.Joiner> methodConsumer) {
    minimumKeepInfo.forEach(
        (reference, joiner) -> {
          DexProgramClass contextClass =
              asProgramClassOrNull(definitions.definitionFor(reference.getContextType()));
          if (contextClass != null) {
            reference.accept(
                clazz -> classConsumer.accept(contextClass, joiner.asClassJoiner()),
                fieldReference -> {
                  ProgramField field = contextClass.lookupProgramField(fieldReference);
                  if (field != null) {
                    fieldConsumer.accept(field, joiner.asFieldJoiner());
                  }
                },
                methodReference -> {
                  ProgramMethod method = contextClass.lookupProgramMethod(methodReference);
                  if (method != null) {
                    methodConsumer.accept(method, joiner.asMethodJoiner());
                  }
                });
          }
        });
  }

  @SuppressWarnings("unchecked")
  public <T extends DexReference> void forEachThatMatches(
      BiPredicate<DexReference, Joiner<?, ?, ?>> predicate,
      BiConsumer<T, KeepInfo.Joiner<?, ?, ?>> consumer) {
    minimumKeepInfo.forEach(
        (reference, minimumKeepInfoForReference) -> {
          if (predicate.test(reference, minimumKeepInfoForReference)) {
            consumer.accept((T) reference, minimumKeepInfoForReference);
          }
        });
  }

  public KeepInfo.Joiner<?, ?, ?> getOrCreateMinimumKeepInfoFor(DexReference reference) {
    return minimumKeepInfo.computeIfAbsent(
        reference, ignoreKey(() -> KeepInfo.newEmptyJoinerFor(reference)));
  }

  public boolean hasMinimumKeepInfoThatMatches(
      DexReference reference, Predicate<KeepInfo.Joiner<?, ?, ?>> predicate) {
    KeepInfo.Joiner<?, ?, ?> minimumKeepInfoForReference = minimumKeepInfo.get(reference);
    return minimumKeepInfoForReference != null && predicate.test(minimumKeepInfoForReference);
  }

  public boolean isEmpty() {
    return minimumKeepInfo.isEmpty();
  }

  public void merge(MinimumKeepInfoCollection otherMinimumKeepInfo) {
    otherMinimumKeepInfo.forEach(this::mergeMinimumKeepInfoFor);
  }

  public void mergeMinimumKeepInfoFor(
      DexReference reference, KeepInfo.Joiner<?, ?, ?> minimumKeepInfoForReference) {
    getOrCreateMinimumKeepInfoFor(reference).mergeUnsafe(minimumKeepInfoForReference);
  }

  public void pruneDeadItems(DexDefinitionSupplier definitions, Enqueuer enqueuer) {
    MapUtils.removeIf(
        minimumKeepInfo,
        (reference, minimumKeepInfoForReference) -> {
          assert !minimumKeepInfoForReference.isBottom();
          ProgramDefinition definition =
              reference.apply(
                  clazz -> asProgramClassOrNull(definitions.definitionFor(clazz)),
                  field ->
                      field.lookupOnProgramClass(
                          asProgramClassOrNull(definitions.definitionFor(field.getHolderType()))),
                  method ->
                      method.lookupOnProgramClass(
                          asProgramClassOrNull(definitions.definitionFor(method.getHolderType()))));
          return definition == null || !enqueuer.isReachable(definition);
        });
  }

  public void pruneItems(PrunedItems prunedItems) {
    minimumKeepInfo.keySet().removeIf(prunedItems::isRemoved);
  }

  public KeepClassInfo.Joiner remove(DexType clazz) {
    return (KeepClassInfo.Joiner) minimumKeepInfo.remove(clazz);
  }

  public KeepFieldInfo.Joiner remove(DexField field) {
    return (KeepFieldInfo.Joiner) minimumKeepInfo.remove(field);
  }

  public KeepMethodInfo.Joiner remove(DexMethod method) {
    return (KeepMethodInfo.Joiner) minimumKeepInfo.remove(method);
  }

  public MinimumKeepInfoCollection rewrittenWithLens(GraphLens graphLens) {
    MinimumKeepInfoCollection rewrittenMinimumKeepInfo = new MinimumKeepInfoCollection();
    forEach(
        (reference, minimumKeepInfoForReference) -> {
          DexReference rewrittenReference =
              reference.apply(
                  type -> {
                    DexType rewrittenType = graphLens.lookupType(type);
                    if (rewrittenType.isPrimitiveType()) {
                      // May happen due to enum unboxing.
                      assert type.isClassType();
                      assert rewrittenType.isIntType();
                      return null;
                    }
                    return rewrittenType;
                  },
                  graphLens::getRenamedFieldSignature,
                  graphLens::getRenamedMethodSignature);
          if (rewrittenReference != null) {
            rewrittenMinimumKeepInfo
                .getOrCreateMinimumKeepInfoFor(rewrittenReference)
                .mergeUnsafe(minimumKeepInfoForReference);
          }
        });
    return rewrittenMinimumKeepInfo;
  }
}
