// Copyright (c) 2022, 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;

import static com.android.tools.r8.synthesis.SyntheticNaming.COMPANION_CLASS_SUFFIX;
import static com.android.tools.r8.synthesis.SyntheticNaming.EXTERNAL_SYNTHETIC_CLASS_SEPARATOR;

import com.android.tools.r8.TextInputStream;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.references.ClassReference;
import com.android.tools.r8.references.MethodReference;
import com.android.tools.r8.references.Reference;
import com.android.tools.r8.startup.StartupProfileBuilder;
import com.android.tools.r8.utils.MethodReferenceUtils;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.function.Consumer;

public class ArtProfileBuilderUtils {

  public interface SyntheticToSyntheticContextGeneralization {

    ClassReference getSyntheticContextReference(ClassReference classReference);

    /**
     * When a startup profile is given to D8, the program input should be dex and the startup
     * profile should have been generated by launching the dex that is given on input. Therefore,
     * synthetic items in the ART profile should be present in the program input to D8 with the
     * exact same synthetic names as in the ART profile. This means that there is no need to
     * generalize synthetic items to their synthetic context.
     */
    static SyntheticToSyntheticContextGeneralization createForD8() {
      return classReference -> null;
    }

    /**
     * When a startup profile is given to R8, the program input is class files and the startup
     * profile should have been generated by dexing the program input (in release and intermediate
     * mode) and then launching the resulting app. The synthetic items in the resulting ART profile
     * do not exist in the program input to R8 (and the same synthetics may receive different names
     * in the R8 compilation). Therefore, synthetic items in the ART profile are generalized into
     * matching all synthetics from their synthetic context.
     */
    static SyntheticToSyntheticContextGeneralization createForR8() {
      return classReference -> {
        // TODO(b/243777722): Move this logic into synthetic items and extend the mapping from
        //  synthetic classes to their synthetic context to all synthetic kinds.
        String classDescriptor = classReference.getDescriptor();
        for (int i = 1; i < classDescriptor.length() - 1; i++) {
          if (classDescriptor.charAt(i) != '$') {
            continue;
          }
          if (classDescriptor.regionMatches(
                  i, COMPANION_CLASS_SUFFIX, 0, COMPANION_CLASS_SUFFIX.length())
              || classDescriptor.regionMatches(
                  i,
                  EXTERNAL_SYNTHETIC_CLASS_SEPARATOR,
                  0,
                  EXTERNAL_SYNTHETIC_CLASS_SEPARATOR.length())) {
            return Reference.classFromDescriptor(classDescriptor.substring(0, i) + ";");
          }
        }
        return null;
      };
    }
  }

  /**
   * Helper for creating an {@link ArtProfileBuilder} that performs callbacks on the given {@param
   * startupProfileBuilder}.
   */
  public static ArtProfileBuilder createBuilderForArtProfileToStartupProfileConversion(
      StartupProfileBuilder startupProfileBuilder,
      SyntheticToSyntheticContextGeneralization syntheticToSyntheticContextGeneralization) {
    return new ArtProfileBuilder() {

      @Override
      public ArtProfileBuilder addClassRule(
          Consumer<ArtProfileClassRuleBuilder> classRuleBuilderConsumer) {
        MutableArtProfileClassRule classRule = new MutableArtProfileClassRule();
        classRuleBuilderConsumer.accept(classRule);
        ClassReference syntheticContextReference =
            syntheticToSyntheticContextGeneralization.getSyntheticContextReference(
                classRule.getClassReference());
        if (syntheticContextReference == null) {
          startupProfileBuilder.addStartupClass(
              startupClassBuilder ->
                  startupClassBuilder.setClassReference(classRule.getClassReference()));
        } else {
          startupProfileBuilder.addSyntheticStartupMethod(
              syntheticStartupMethodBuilder ->
                  syntheticStartupMethodBuilder.setSyntheticContextReference(
                      syntheticContextReference));
        }
        return this;
      }

      @Override
      public ArtProfileBuilder addMethodRule(
          Consumer<ArtProfileMethodRuleBuilder> methodRuleBuilderConsumer) {
        MutableArtProfileMethodRule methodRule = new MutableArtProfileMethodRule();
        methodRuleBuilderConsumer.accept(methodRule);
        ClassReference syntheticContextReference =
            syntheticToSyntheticContextGeneralization.getSyntheticContextReference(
                methodRule.getMethodReference().getHolderClass());
        if (syntheticContextReference == null) {
          startupProfileBuilder.addStartupMethod(
              startupMethodBuilder ->
                  startupMethodBuilder.setMethodReference(methodRule.getMethodReference()));
        } else {
          startupProfileBuilder.addSyntheticStartupMethod(
              syntheticStartupMethodBuilder ->
                  syntheticStartupMethodBuilder.setSyntheticContextReference(
                      syntheticContextReference));
        }
        return this;
      }

      @Override
      public ArtProfileBuilder addHumanReadableArtProfile(
          TextInputStream textInputStream,
          Consumer<HumanReadableArtProfileParserBuilder> parserBuilderConsumer) {
        // The ART profile parser never calls addHumanReadableArtProfile().
        throw new Unreachable();
      }
    };
  }

  static class MutableArtProfileClassRule implements ArtProfileClassRuleBuilder {

    private ClassReference classReference;

    MutableArtProfileClassRule() {}

    public ClassReference getClassReference() {
      return classReference;
    }

    @Override
    public ArtProfileClassRuleBuilder setClassReference(ClassReference classReference) {
      this.classReference = classReference;
      return this;
    }

    public ArtProfileClassRuleInfo getClassRuleInfo() {
      return ArtProfileClassRuleInfoImpl.empty();
    }

    public void writeHumanReadableRuleString(OutputStreamWriter writer) throws IOException {
      writer.write(classReference.getDescriptor());
    }
  }

  static class MutableArtProfileMethodRule implements ArtProfileMethodRuleBuilder {

    private MethodReference methodReference;
    private ArtProfileMethodRuleInfoImpl methodRuleInfo = ArtProfileMethodRuleInfoImpl.empty();

    MutableArtProfileMethodRule() {}

    public MethodReference getMethodReference() {
      return methodReference;
    }

    public ArtProfileMethodRuleInfo getMethodRuleInfo() {
      return methodRuleInfo;
    }

    @Override
    public ArtProfileMethodRuleBuilder setMethodReference(MethodReference methodReference) {
      this.methodReference = methodReference;
      return this;
    }

    @Override
    public ArtProfileMethodRuleBuilder setMethodRuleInfo(
        Consumer<ArtProfileMethodRuleInfoBuilder> methodRuleInfoBuilderConsumer) {
      ArtProfileMethodRuleInfoImpl.Builder methodRuleInfoBuilder =
          ArtProfileMethodRuleInfoImpl.builder();
      methodRuleInfoBuilderConsumer.accept(methodRuleInfoBuilder);
      methodRuleInfo = methodRuleInfoBuilder.build();
      return this;
    }

    public void writeHumanReadableRuleString(OutputStreamWriter writer) throws IOException {
      methodRuleInfo.writeHumanReadableFlags(writer);
      writer.write(MethodReferenceUtils.toSmaliString(methodReference));
    }
  }
}
