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

import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;

import com.android.tools.r8.R8Command;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.ToolHelper.ProcessResult;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.FileUtils;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.FieldAccessInstructionSubject;
import com.android.tools.r8.utils.codeinspector.InstructionSubject;
import com.android.tools.r8.utils.codeinspector.MethodSubject;
import com.google.common.collect.ImmutableList;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.function.Function;
import org.junit.Assume;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import regress_76025099.Main;
import regress_76025099.impl.Impl;

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

  private Backend backend;

  @Parameterized.Parameters(name = "Backend: {0}")
  public static Collection<Backend> data() {
    return Arrays.asList(Backend.values());
  }

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

  private static final String PRG =
      ToolHelper.EXAMPLES_BUILD_DIR + "regress_76025099" + FileUtils.JAR_EXTENSION;

  private AndroidApp runR8(AndroidApp app) throws Exception {
    R8Command command =
        ToolHelper.addProguardConfigurationConsumer(
                ToolHelper.prepareR8CommandBuilder(app, emptyConsumer(backend)),
                pgConfig -> {
                  pgConfig.setPrintMapping(true);
                  pgConfig.setPrintMappingFile(map);
                })
            .addLibraryFiles(runtimeJar(backend))
            .addProguardConfigurationFiles(pgConfig)
            .setOutput(tempRoot.toPath(), outputMode(backend))
            .build();
    return ToolHelper.runR8(command, o -> {
      o.enableMinification = false;
    });
  }

  private File tempRoot;
  private Path jarPath;
  private AndroidApp originalApp;
  private String mainName;
  private Path pgConfig;
  private Path map;

  @Before
  public void setUp() throws Exception {
    tempRoot = temp.getRoot();
    jarPath = Paths.get(PRG);
    originalApp = readJar(jarPath);
    mainName = Main.class.getCanonicalName();
    pgConfig = File.createTempFile("keep-rules", ".config", tempRoot).toPath();
    String config = keepMainProguardConfiguration(Main.class);
    config += System.lineSeparator() + "-dontobfuscate";
    Files.write(pgConfig, config.getBytes());
    map = File.createTempFile("proguard", ".map", tempRoot).toPath();
  }

  @Test
  public void testProguardAndD8() throws Exception {
    Assume.assumeTrue(backend == Backend.DEX);
    if (!isRunProguard()) {
      return;
    }

    ProcessResult jvmOutput = ToolHelper.runJava(ImmutableList.of(jarPath), mainName);
    assertEquals(0, jvmOutput.exitCode);

    Path proguarded =
        File.createTempFile("proguarded", FileUtils.JAR_EXTENSION, tempRoot).toPath();
    ProcessResult proguardResult = ToolHelper.runProguardRaw(jarPath, proguarded, pgConfig, map);
    assertEquals(0, proguardResult.exitCode);

    AndroidApp processedApp = ToolHelper.runD8(readJar(proguarded));
    verifyFieldAccess(processedApp, jvmOutput);
  }

  @Test
  public void testR8() throws Exception {
    ProcessResult jvmOutput = ToolHelper.runJava(ImmutableList.of(jarPath), mainName);
    assertEquals(0, jvmOutput.exitCode);

    AndroidApp processedApp = runR8(originalApp);
    verifyFieldAccess(processedApp, jvmOutput);
  }

  private static InstructionSubject findInstructionOrNull(
      Iterator<InstructionSubject> iterator, Function<InstructionSubject, Boolean> predicate) {
    while (iterator.hasNext()) {
      InstructionSubject instruction = iterator.next();
      if (predicate.apply(instruction)) {
        return instruction;
      }
    }
    return null;
  }

  private void verifyFieldAccess(AndroidApp processedApp, ProcessResult jvmOutput)
      throws Exception {
    CodeInspector inspector = new CodeInspector(processedApp);
    ClassSubject impl = inspector.clazz(Impl.class);
    assertThat(impl, isPresent());
    MethodSubject init = impl.init(ImmutableList.of("java.lang.String"));
    assertThat(init, isPresent());
    Iterator<InstructionSubject> iterator = init.iterateInstructions();

    assertNotNull(findInstructionOrNull(iterator, InstructionSubject::isInvoke));

    InstructionSubject instruction =
        findInstructionOrNull(iterator, InstructionSubject::isInstancePut);
    assertNotNull(instruction);
    FieldAccessInstructionSubject fieldAccessInstruction =
        (FieldAccessInstructionSubject) instruction;
    assertEquals("name", fieldAccessInstruction.name());
    assertTrue(fieldAccessInstruction.holder().is(impl.getDexClass().type.toString()));

    assertNotNull(findInstructionOrNull(iterator, InstructionSubject::isReturnVoid));

    ProcessResult output;
    if (backend == Backend.DEX) {
      output = runOnArtRaw(processedApp, mainName);
    } else {
      assert backend == Backend.CF;
      output = runOnJavaRaw(processedApp, mainName, Collections.emptyList());
    }
    assertEquals(0, output.exitCode);
    assertEquals(jvmOutput.stdout, output.stdout);
  }

}
