// 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.naming.applymapping;

import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static org.junit.Assert.assertEquals;
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.graph.DexMethod;
import com.android.tools.r8.origin.Origin;
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.InstructionSubject;
import com.android.tools.r8.utils.codeinspector.InvokeInstructionSubject;
import com.android.tools.r8.utils.codeinspector.MethodSubject;
import com.google.common.collect.ImmutableList;
import java.nio.file.Path;
import java.util.Iterator;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

// Base -> X:
class Base {
  // foo() -> bar
  void foo() {
    System.out.println("Base#foo");
  }
}

// Sub -> Y:
class Sub extends Base {
  // foo() -> bar
  // Sub#foo ~> Base#foo by member rebinding analysis
}

class CompositionalLenseTestMain {
  public static void main(String[] args) {
    // Without regard to the order of member rebinding and apply mapping,
    // this call should be mapped to X.bar(), not Y.bar() nor Base.foo().
    new Sub().foo();
  }
}

@RunWith(Parameterized.class)
public class CompositionalLenseTest extends TestBase {
  private final static List<Class> CLASSES =
      ImmutableList.of(Base.class, Sub.class, CompositionalLenseTestMain.class);

  private Backend backend;

  @Parameterized.Parameters(name = "Backend: {0}")
  public static Backend[] data() {
    return Backend.values();
  }

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

  @Test
  public void test() throws Exception {
    Path mapPath = temp.newFile("test-mapping.txt").toPath();
    List<String> pgMap = ImmutableList.of(
        "com.android.tools.r8.naming.applymapping.Base -> X:",
        "  void foo() -> bar",
        "com.android.tools.r8.naming.applymapping.Sub -> Y:",
        "  void foo() -> bar"
    );
    FileUtils.writeTextFile(mapPath, pgMap);

    AndroidApp app = readClasses(CLASSES);
    R8Command.Builder builder = ToolHelper.prepareR8CommandBuilder(app, emptyConsumer(backend));
    builder
        .addProguardConfiguration(
            ImmutableList.of(
                keepMainProguardConfiguration(CompositionalLenseTestMain.class),
                "-applymapping " + mapPath,
                "-dontobfuscate"), // to use the renamed names in test-mapping.txt
            Origin.unknown())
        .addLibraryFiles(runtimeJar(backend));
    AndroidApp processedApp =
        ToolHelper.runR8(
            builder.build(),
            options -> {
              options.enableInlining = false;
              options.enableVerticalClassMerging = false;
            });
    CodeInspector codeInspector = new CodeInspector(processedApp);
    ClassSubject classSubject = codeInspector.clazz(CompositionalLenseTestMain.class);
    assertThat(classSubject, isPresent());
    MethodSubject methodSubject = classSubject.method(CodeInspector.MAIN);
    assertThat(methodSubject, isPresent());
    Iterator<InstructionSubject> iterator = methodSubject.iterateInstructions();

    InstructionSubject instruction = null;
    boolean found = false;
    while (iterator.hasNext()) {
      instruction = iterator.next();
      if (instruction.isInvokeVirtual()) {
        found = true;
        break;
      }
    }
    assertTrue(found);

    DexMethod invokedMethod = ((InvokeInstructionSubject) instruction).invokedMethod();
    assertEquals("bar", invokedMethod.name.toString());
    assertEquals("X", invokedMethod.getHolder().getName());
  }
}
