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

import com.android.tools.r8.R8Command;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.accessrelaxation.privateinstance.Base;
import com.android.tools.r8.accessrelaxation.privateinstance.Sub1;
import com.android.tools.r8.accessrelaxation.privateinstance.Sub2;
import com.android.tools.r8.accessrelaxation.privateinstance.TestMain;
import com.android.tools.r8.accessrelaxation.privatestatic.A;
import com.android.tools.r8.accessrelaxation.privatestatic.B;
import com.android.tools.r8.accessrelaxation.privatestatic.BB;
import com.android.tools.r8.accessrelaxation.privatestatic.C;
import com.android.tools.r8.naming.MemberNaming.MethodSignature;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.DexInspector;
import com.google.common.collect.ImmutableList;
import org.junit.Test;

public final class NonConstructorRelaxationTest extends AccessRelaxationTestBase {
  private static final String STRING = "java.lang.String";

  @Test
  public void testStaticMethodRelaxation() throws Exception {
    Class mainClass = C.class;
    R8Command.Builder builder = loadProgramFiles(mainClass.getPackage());

    // Note: we use '-checkdiscard' to indirectly check that the access relaxation is
    // done which leads to inlining of all pB*** methods so they are removed. Without
    // access relaxation inlining is not performed and method are kept.
    builder.addProguardConfiguration(
        ImmutableList.of(
            "-keep class " + mainClass.getCanonicalName() + "{",
            "  public static void main(java.lang.String[]);",
            "}",
            "",
            "-checkdiscard class " + A.class.getCanonicalName() + "{",
            "  *** pBaz();",
            "  *** pBar();",
            "  *** pBar1();",
            "  *** pBlah1();",
            "}",
            "",
            "-checkdiscard class " + B.class.getCanonicalName() + "{",
            "  *** pBlah1();",
            "}",
            "",
            "-checkdiscard class " + BB.class.getCanonicalName() + "{",
            "  *** pBlah1();",
            "}",
            "",
            "-dontobfuscate",
            "-allowaccessmodification"
        ),
        Origin.unknown());

    AndroidApp app = ToolHelper.runR8(builder.build());
    compareJvmAndArt(app, mainClass);

    DexInspector dexInspector = new DexInspector(app);
    assertPublic(dexInspector, A.class,
        new MethodSignature("baz", STRING, ImmutableList.of()));
    assertPublic(dexInspector, A.class,
        new MethodSignature("bar", STRING, ImmutableList.of()));
    assertPublic(dexInspector, A.class,
        new MethodSignature("bar", STRING, ImmutableList.of("int")));
    assertPublic(dexInspector, A.class,
        new MethodSignature("blah", STRING, ImmutableList.of("int")));

    assertPublic(dexInspector, B.class,
        new MethodSignature("blah", STRING, ImmutableList.of("int")));

    assertPublic(dexInspector, BB.class,
        new MethodSignature("blah", STRING, ImmutableList.of("int")));
  }

  @Test
  public void testInstanceMethodRelaxation() throws Exception {
    Class mainClass = TestMain.class;
    R8Command.Builder builder = loadProgramFiles(mainClass.getPackage());

    builder.addProguardConfiguration(
        ImmutableList.of(
            "-keep class " + mainClass.getCanonicalName() + "{",
            "  public static void main(java.lang.String[]);",
            "}",
            "",
            "-checkdiscard class " + Base.class.getCanonicalName() + "{",
            "  *** p*();",
            "}",
            "",
            "-checkdiscard class " + Sub1.class.getCanonicalName() + "{",
            "  *** p*();",
            "}",
            "",
            "-checkdiscard class " + Sub2.class.getCanonicalName() + "{",
            "  *** p*();",
            "}",
            "",
            "-dontobfuscate",
            "-allowaccessmodification"
        ),
        Origin.unknown());

    AndroidApp app = ToolHelper.runR8(builder.build());
    compareJvmAndArt(app, mainClass);

    DexInspector dexInspector = new DexInspector(app);
    assertPublic(dexInspector, Base.class,
        new MethodSignature("foo", STRING, ImmutableList.of()));

    // Base#foo?() can't be publicized due to Itf<1>#foo<1>().
    assertNotPublic(dexInspector, Base.class,
        new MethodSignature("foo1", STRING, ImmutableList.of()));
    assertNotPublic(dexInspector, Base.class,
        new MethodSignature("foo2", STRING, ImmutableList.of()));

    // Sub?#bar1(int) can be publicized as they don't bother each other.
    assertPublic(dexInspector, Sub1.class,
        new MethodSignature("bar1", STRING, ImmutableList.of("int")));
    assertPublic(dexInspector, Sub2.class,
        new MethodSignature("bar1", STRING, ImmutableList.of("int")));

    // Sub2#bar2(int) is unique throughout the hierarchy, hence publicized.
    assertPublic(dexInspector, Sub2.class,
        new MethodSignature("bar2", STRING, ImmutableList.of("int")));
  }
}
