// 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 org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import com.android.tools.r8.DiagnosticsHandler;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.origin.Origin;
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.utils.AndroidApiLevel;
import com.android.tools.r8.utils.MethodReferenceUtils;
import com.google.common.collect.Lists;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;

@RunWith(Parameterized.class)
public class ArtProfilePassthroughTest extends TestBase {

  enum ProviderStatus {
    PENDING,
    ACTIVE,
    DONE
  }

  private static final ClassReference mainClassReference = Reference.classFromClass(Main.class);
  private static final MethodReference mainMethodReference =
      MethodReferenceUtils.mainMethod(Main.class);

  @Parameter(0)
  public TestParameters parameters;

  @Parameters(name = "{0}")
  public static TestParametersCollection data() {
    return getTestParameters().withNoneRuntime().build();
  }

  @Test
  public void testD8() throws Exception {
    ArtProfileProviderForTesting artProfileProvider = new ArtProfileProviderForTesting();
    ArtProfileConsumerForTesting residualArtProfileConsumer =
        new ArtProfileConsumerForTesting(artProfileProvider);
    testForD8(Backend.DEX)
        .addProgramClasses(Main.class)
        // Add a profile provider and consumer that verifies that the profile is being provided at
        // the same time it is being consumed.
        .addArtProfileForRewriting(artProfileProvider, residualArtProfileConsumer)
        .release()
        .setMinApi(AndroidApiLevel.LATEST)
        .compile();

    // Verify that the profile input was processed.
    assertEquals(ProviderStatus.DONE, artProfileProvider.providerStatus);
    assertTrue(residualArtProfileConsumer.finished);
    assertEquals(
        Lists.newArrayList(mainClassReference, mainMethodReference),
        residualArtProfileConsumer.references);
  }

  static class ArtProfileProviderForTesting implements ArtProfileProvider {

    ProviderStatus providerStatus = ProviderStatus.PENDING;

    @Override
    public void getArtProfile(ArtProfileBuilder profileBuilder) {
      providerStatus = ProviderStatus.ACTIVE;
      profileBuilder
          .addClassRule(classRuleBuilder -> classRuleBuilder.setClassReference(mainClassReference))
          .addMethodRule(
              methodRuleBuilder -> methodRuleBuilder.setMethodReference(mainMethodReference));
      providerStatus = ProviderStatus.DONE;
    }

    @Override
    public Origin getOrigin() {
      return Origin.unknown();
    }
  }

  static class ArtProfileConsumerForTesting implements ArtProfileConsumer {

    private final ArtProfileProviderForTesting artProfileProvider;

    List<Object> references = new ArrayList<>();
    boolean finished;

    ArtProfileConsumerForTesting(ArtProfileProviderForTesting artProfileProvider) {
      this.artProfileProvider = artProfileProvider;
    }

    @Override
    public ArtProfileRuleConsumer getRuleConsumer() {
      // The compiler should not request to get the profile from the provider before getting the
      // consumer.
      assertTrue(artProfileProvider.providerStatus == ProviderStatus.PENDING);
      return new ArtProfileRuleConsumer() {
        @Override
        public void acceptClassRule(
            ClassReference classReference, ArtProfileClassRuleInfo classRuleInfo) {
          // The consumer should only be receiving callbacks while the profile is being
          // provided.
          assertTrue(artProfileProvider.providerStatus == ProviderStatus.ACTIVE);
          references.add(classReference);
        }

        @Override
        public void acceptMethodRule(
            MethodReference methodReference, ArtProfileMethodRuleInfo methodRuleInfo) {
          // The consumer should only be receiving callbacks while the profile is being
          // provided.
          assertTrue(artProfileProvider.providerStatus == ProviderStatus.ACTIVE);
          references.add(methodReference);
        }
      };
    }

    @Override
    public void finished(DiagnosticsHandler handler) {
      // The profile should be fully provided when all data is given to the consumer.
      assertTrue(artProfileProvider.providerStatus == ProviderStatus.DONE);
      finished = true;
    }
  }

  static class Main {

    public static void main(String[] args) {}
  }
}
