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

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;

import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.R8Command;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.utils.AndroidAppConsumers;
import com.android.tools.r8.utils.InternalOptions.LineNumberOptimization;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.InstructionSubject;
import com.android.tools.r8.utils.codeinspector.LineNumberTable;
import com.android.tools.r8.utils.codeinspector.MethodSubject;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Streams;
import it.unimi.dsi.fastutil.ints.IntCollection;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

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

  private static final Class CLASS = ShareCommonCodeOnDistinctPositionsTest.class;

  @Parameters(name = "Backend: {0}")
  public static Backend[] parameters() {
    return ToolHelper.getBackends();
  }

  private final Backend backend;

  public ShareCommonCodeOnDistinctPositionsTestRunner(Backend backend) {
    this.backend = backend;
  }

  @Test
  public void test() throws CompilationFailedException, IOException, ExecutionException {
    AndroidAppConsumers sink = new AndroidAppConsumers();
    ToolHelper.runR8(
        R8Command.builder()
            .addLibraryFiles(runtimeJar(backend))
            .addProgramFiles(ToolHelper.getClassFileForTestClass(CLASS))
            .setProgramConsumer(sink.wrapProgramConsumer(emptyConsumer(backend)))
            .setDisableMinification(true)
            .setDisableTreeShaking(true)
            .addProguardConfiguration(
                ImmutableList.of("-keepattributes LineNumberTable"), Origin.unknown())
            .build(),
        options -> options.lineNumberOptimization = LineNumberOptimization.OFF);
    CodeInspector inspector = new CodeInspector(sink.build());
    MethodSubject method = inspector.clazz(CLASS).mainMethod();
    // Check that the two shared lines are not in the output (they have no throwing instructions).
    LineNumberTable lineNumberTable = method.getLineNumberTable();
    IntCollection lines = lineNumberTable.getLines();
    assertFalse(lines.contains(12));
    assertFalse(lines.contains(14));
    // Check that the two lines have been shared, e.g., there may be only one multiplication left.
    assertEquals(
        "Expected only one multiplcation due to instruction sharing.",
        1,
        Streams.stream(method.iterateInstructions())
            .filter(InstructionSubject::isMultiplication)
            .count());
  }
}
