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

import static com.android.tools.r8.utils.dexinspector.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.code.InvokeVirtual;
import com.android.tools.r8.graph.DexCode;
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.dexinspector.ClassSubject;
import com.android.tools.r8.utils.dexinspector.DexInspector;
import com.android.tools.r8.utils.dexinspector.MethodSubject;
import com.google.common.collect.ImmutableList;
import java.nio.file.Path;
import java.util.List;
import org.junit.Test;

// 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 TestMain {
  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();
  }
}

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

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

    AndroidApp app = readClasses(CLASSES);
    R8Command.Builder builder = ToolHelper.prepareR8CommandBuilder(app);
    builder.addProguardConfiguration(
        ImmutableList.of(
            keepMainProguardConfiguration(TestMain.class),
            "-applymapping " + mapPath,
            "-dontobfuscate"),  // to use the renamed names in test-mapping.txt
        Origin.unknown());
    AndroidApp processedApp = ToolHelper.runR8(builder.build(), options -> {
      options.enableInlining = false;
      options.enableClassMerging = false;
    });
    DexInspector dexInspector = new DexInspector(processedApp);
    ClassSubject classSubject = dexInspector.clazz(TestMain.class);
    assertThat(classSubject, isPresent());
    MethodSubject methodSubject = classSubject.method(DexInspector.MAIN);
    assertThat(methodSubject, isPresent());
    DexCode dexCode = methodSubject.getMethod().getCode().asDexCode();
    assertTrue(dexCode.instructions[2] instanceof InvokeVirtual);
    InvokeVirtual invoke = (InvokeVirtual) dexCode.instructions[2];
    DexMethod invokedMethod = invoke.getMethod();
    assertEquals("bar", invokedMethod.name.toString());
    assertEquals("X", invokedMethod.getHolder().getName());
  }
}
