// Copyright (c) 2023, 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.profile.art.rewriting;

import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexReference;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.ProgramDefinition;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.profile.art.ArtProfile;
import com.android.tools.r8.profile.art.ArtProfileClassRule;
import com.android.tools.r8.profile.art.ArtProfileMethodRule;
import com.android.tools.r8.profile.art.ArtProfileRule;
import com.google.common.collect.Sets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;
import java.util.function.Function;

/** Mutable extension of an existing ArtProfile. */
public class ArtProfileAdditions {

  public interface ArtProfileAdditionsBuilder {

    ArtProfileAdditionsBuilder addRule(ProgramDefinition definition);

    ArtProfileAdditionsBuilder addRule(DexReference reference);

    ArtProfileAdditionsBuilder removeMovedMethodRule(
        ProgramMethod oldMethod, ProgramMethod newMethod);
  }

  private ArtProfile artProfile;

  private final Map<DexType, ArtProfileClassRule.Builder> classRuleAdditions =
      new ConcurrentHashMap<>();
  private final Map<DexMethod, ArtProfileMethodRule.Builder> methodRuleAdditions =
      new ConcurrentHashMap<>();
  private final Set<DexMethod> methodRuleRemovals = Sets.newConcurrentHashSet();

  ArtProfileAdditions(ArtProfile artProfile) {
    this.artProfile = artProfile;
  }

  void applyIfContextIsInProfile(
      DexMethod context, Consumer<ArtProfileAdditionsBuilder> builderConsumer) {
    ArtProfileMethodRule contextMethodRule = artProfile.getMethodRule(context);
    if (contextMethodRule != null) {
      builderConsumer.accept(
          new ArtProfileAdditionsBuilder() {

            @Override
            public ArtProfileAdditionsBuilder addRule(ProgramDefinition definition) {
              return addRule(definition.getReference());
            }

            @Override
            public ArtProfileAdditionsBuilder addRule(DexReference reference) {
              addRuleFromContext(
                  reference, contextMethodRule, MethodRuleAdditionConfig.getDefault());
              return this;
            }

            @Override
            public ArtProfileAdditionsBuilder removeMovedMethodRule(
                ProgramMethod oldMethod, ProgramMethod newMethod) {
              ArtProfileAdditions.this.removeMovedMethodRule(oldMethod, newMethod);
              return this;
            }
          });
    }
  }

  private void addRuleFromContext(
      DexReference reference,
      ArtProfileMethodRule contextMethodRule,
      MethodRuleAdditionConfig config) {
    if (reference.isDexType()) {
      addClassRule(reference.asDexType());
    } else {
      assert reference.isDexMethod();
      addMethodRuleFromContext(reference.asDexMethod(), contextMethodRule, config);
    }
  }

  private void addClassRule(DexType type) {
    if (artProfile.containsClassRule(type)) {
      return;
    }

    // Create profile rule for class.
    classRuleAdditions.computeIfAbsent(type, key -> ArtProfileClassRule.builder().setType(key));
  }

  private void addMethodRuleFromContext(
      DexMethod method, ArtProfileMethodRule contextMethodRule, MethodRuleAdditionConfig config) {
    // Create profile rule for method.
    ArtProfileMethodRule.Builder methodRuleBuilder =
        methodRuleAdditions.computeIfAbsent(
            method, methodReference -> ArtProfileMethodRule.builder().setMethod(method));

    // Setup the rule.
    synchronized (methodRuleBuilder) {
      methodRuleBuilder.acceptMethodRuleInfoBuilder(
          methodRuleInfoBuilder ->
              config.configureMethodRuleInfo(methodRuleInfoBuilder, contextMethodRule));
    }
  }

  void removeMovedMethodRule(ProgramMethod oldMethod, ProgramMethod newMethod) {
    assert artProfile.containsMethodRule(oldMethod.getReference());
    assert methodRuleAdditions.containsKey(newMethod.getReference());
    methodRuleRemovals.add(oldMethod.getReference());
  }

  ArtProfile createNewArtProfile() {
    if (!hasAdditions()) {
      assert !hasRemovals();
      return artProfile;
    }

    // Add existing rules to new profile.
    ArtProfile.Builder artProfileBuilder = ArtProfile.builder();
    artProfile.forEachRule(
        artProfileBuilder::addRule,
        methodRule -> {
          if (!methodRuleRemovals.contains(methodRule.getMethod())) {
            artProfileBuilder.addRule(methodRule);
          }
        });

    // Sort and add additions to new profile. Sorting is needed since the additions to this
    // collection may be concurrent.
    List<ArtProfileRule> ruleAdditionsSorted =
        new ArrayList<>(classRuleAdditions.size() + methodRuleAdditions.size());
    classRuleAdditions
        .values()
        .forEach(classRuleBuilder -> ruleAdditionsSorted.add(classRuleBuilder.build()));
    methodRuleAdditions
        .values()
        .forEach(methodRuleBuilder -> ruleAdditionsSorted.add(methodRuleBuilder.build()));
    ruleAdditionsSorted.sort(ArtProfileRule::compareTo);
    artProfileBuilder.addRules(ruleAdditionsSorted);

    return artProfileBuilder.build();
  }

  boolean hasAdditions() {
    return !classRuleAdditions.isEmpty() || !methodRuleAdditions.isEmpty();
  }

  private boolean hasRemovals() {
    return !methodRuleRemovals.isEmpty();
  }

  ArtProfileAdditions rewriteMethodReferences(Function<DexMethod, DexMethod> methodFn) {
    ArtProfileAdditions rewrittenAdditions = new ArtProfileAdditions(artProfile);
    assert classRuleAdditions.isEmpty();
    assert methodRuleRemovals.isEmpty();
    methodRuleAdditions.forEach(
        (method, methodRuleBuilder) -> {
          DexMethod newMethod = methodFn.apply(method);
          ArtProfileMethodRule.Builder existingMethodRuleBuilder =
              rewrittenAdditions.methodRuleAdditions.put(
                  newMethod, methodRuleBuilder.setMethod(newMethod));
          assert existingMethodRuleBuilder == null;
        });
    return rewrittenAdditions;
  }

  void setArtProfile(ArtProfile artProfile) {
    this.artProfile = artProfile;
  }
}
