// Copyright (c) 2018, 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.maindexlist.whyareyoukeeping;

import static org.junit.Assert.assertEquals;

import com.android.tools.r8.GenerateMainDexList;
import com.android.tools.r8.GenerateMainDexListCommand;
import com.android.tools.r8.R8FullTestBuilder;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.experimental.graphinfo.GraphConsumer;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.references.Reference;
import com.android.tools.r8.shaking.WhyAreYouKeepingConsumer;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.ListUtils;
import com.android.tools.r8.utils.StringUtils;
import com.google.common.collect.ImmutableList;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

class HelloWorldMain {
  public static void main(String[] args) {
    System.out.println(new MainDexClass());
  }
}

class MainDexClass {}

class NonMainDexClass {}

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

  private static final List<Class<?>> CLASSES =
      ImmutableList.of(HelloWorldMain.class, MainDexClass.class, NonMainDexClass.class);

  private enum Command {
    R8,
    Generator
  }

  private enum ApiUse {
    WhyAreYouKeepingRule,
    KeptGraphConsumer
  }

  @Parameters(name = "{0} {1}")
  public static List<Object[]> parameters() {
    return buildParameters(Command.values(), ApiUse.values());
  }

  private final Command command;
  private final ApiUse apiUse;

  public MainDexListWhyAreYouKeeping(Command command, ApiUse apiUse) {
    this.command = command;
    this.apiUse = apiUse;
  }

  public void runTestWithGenerator(GraphConsumer consumer, String rule) throws Exception {
    GenerateMainDexListCommand.Builder builder =
        GenerateMainDexListCommand.builder()
            .addProgramFiles(ListUtils.map(CLASSES, ToolHelper::getClassFileForTestClass))
            .addLibraryFiles(ToolHelper.getDefaultAndroidJar())
            .addMainDexRules(
                ImmutableList.of(keepMainProguardConfiguration(HelloWorldMain.class)),
                Origin.unknown())
            .setMainDexKeptGraphConsumer(consumer);
    if (rule != null) {
      builder.addMainDexRules(ImmutableList.of(rule), Origin.unknown());
    }
    GenerateMainDexList.run(builder.build());
  }

  public void runTestWithR8(GraphConsumer consumer, String rule) throws Exception {
    R8FullTestBuilder builder =
        testForR8(Backend.DEX)
            .noTreeShaking()
            .noMinification()
            .setMinApi(AndroidApiLevel.K)
            .addProgramClasses(CLASSES)
            .addMainDexRules(keepMainProguardConfiguration(HelloWorldMain.class))
            .setMainDexKeptGraphConsumer(consumer);
    if (rule != null) {
      builder.addMainDexRules(rule);
    }
    builder.compile();
  }

  private String runTest(Class clazz) throws Exception {
    PrintStream stdout = System.out;
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    String rule = null;
    WhyAreYouKeepingConsumer consumer = null;
    if (apiUse == ApiUse.KeptGraphConsumer) {
      consumer = new WhyAreYouKeepingConsumer(null);
    } else {
      assert apiUse == ApiUse.WhyAreYouKeepingRule;
      rule = "-whyareyoukeeping class " + clazz.getTypeName();
      System.setOut(new PrintStream(baos));
    }
    switch (command) {
      case R8:
        runTestWithR8(consumer, rule);
        break;
      case Generator:
        runTestWithGenerator(consumer, rule);
        break;
      default:
        throw new Unreachable();
    }
    if (consumer != null) {
      consumer.printWhyAreYouKeeping(Reference.classFromClass(clazz), new PrintStream(baos));
    } else {
      System.setOut(stdout);
    }
    return baos.toString();
  }

  @Test
  public void testMainDexClassWhyAreYouKeeping() throws Exception {
    String expected =
        StringUtils.lines(
            "com.android.tools.r8.maindexlist.whyareyoukeeping.MainDexClass",
            "|- is instantiated in:",
            "|  void " + HelloWorldMain.class.getTypeName() + ".main(java.lang.String[])",
            "|- is referenced in keep rule:",
            "|  -keep class " + HelloWorldMain.class.getTypeName() + " {",
            "|    public static void main(java.lang.String[]);",
            "|  }");
    assertEquals(expected, runTest(MainDexClass.class));
  }

  @Test
  public void testNonMainDexWhyAreYouKeeping() throws Exception {
    String expected =
        StringUtils.lines(
            "Nothing is keeping com.android.tools.r8.maindexlist.whyareyoukeeping.NonMainDexClass");
    assertEquals(expected, runTest(NonMainDexClass.class));
  }
}
