// 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.shaking.ifrule.verticalclassmerging;

import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.IsNot.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;

import com.android.tools.r8.TestParameters;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.FoundMethodSubject;
import com.google.common.collect.ImmutableList;
import java.util.List;
import java.util.stream.Collectors;

public class MergedParameterTypeTest extends MergedTypeBaseTest {

  static class TestClass {

    public static void main(String[] args) {
      method(new B());
    }

    public static void method(A obj) {
      System.out.print(obj.getClass().getName());
    }
  }

  public MergedParameterTypeTest(TestParameters parameters, boolean enableVerticalClassMerging) {
    super(parameters, enableVerticalClassMerging);
  }

  @Override
  public Class<?> getTestClass() {
    return TestClass.class;
  }

  @Override
  public String getConditionForProguardIfRule() {
    return "-if class **$TestClass { void method(**$A); }";
  }

  @Override
  public String getExpectedStdout() {
    return B.class.getName();
  }

  public static class MergedParameterTypeWithCollisionTest extends MergedTypeBaseTest {

    static class SuperTestClass {

      public static void method(A obj) {
        System.out.print(obj.getClass().getName());
      }
    }

    static class TestClass extends SuperTestClass {

      public static void main(String[] args) {
        B obj = new B();
        if (obj == null) {
          TestClass.method(obj);
        }
        SuperTestClass.method(obj);
      }

      public static void method(A obj) {
        System.out.print(obj.getClass().getName());
      }
    }

    public MergedParameterTypeWithCollisionTest(
        TestParameters parameters, boolean enableVerticalClassMerging) {
      super(parameters, enableVerticalClassMerging, ImmutableList.of(SuperTestClass.class));
    }

    @Override
    public Class<?> getTestClass() {
      return TestClass.class;
    }

    @Override
    public String getConditionForProguardIfRule() {
      return "-if class **$SuperTestClass { void method(**$A); }";
    }

    @Override
    public String getExpectedStdout() {
      return B.class.getName();
    }

    @Override
    public void inspect(CodeInspector inspector) {
      super.inspect(inspector);

      ClassSubject testClassSubject = inspector.clazz(TestClass.class);
      assertThat(testClassSubject, isPresent());

      if (enableVerticalClassMerging) {
        // Verify that SuperTestClass has been merged into TestClass.
        assertThat(inspector.clazz(SuperTestClass.class), not(isPresent()));
        assertEquals("java.lang.Object", testClassSubject.getDexClass().superType.toSourceString());

        // Verify that TestClass.method has been removed.
        List<FoundMethodSubject> methods =
            testClassSubject.allMethods().stream()
                .filter(subject -> subject.getFinalName().contains("method"))
                .collect(Collectors.toList());
        assertEquals(1, methods.size());

        // Verify that there was a naming conflict such that SuperTestClass.method was renamed.
        assertNotEquals("method", methods.get(0).getFinalName());
      }
    }
  }
}
