// Copyright (c) 2019, 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.ir.analysis.sideeffect;

import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertTrue;

import com.android.tools.r8.NeverInline;
import com.android.tools.r8.NoVerticalClassMerging;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.FieldSubject;
import com.android.tools.r8.utils.codeinspector.InstructionSubject;
import com.android.tools.r8.utils.codeinspector.MethodSubject;
import com.google.common.collect.ImmutableList;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

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

  private final TestParameters parameters;

  @Parameters(name = "{0}")
  public static TestParametersCollection data() {
    return getTestParameters().withAllRuntimesAndApiLevels().build();
  }

  public PutObjectWithFinalizeTest(TestParameters parameters) {
    this.parameters = parameters;
  }

  @Test
  public void test() throws Exception {
    testForR8(parameters.getBackend())
        .addInnerClasses(PutObjectWithFinalizeTest.class)
        .addKeepMainRule(TestClass.class)
        // The class staticizer does not consider the finalize() method.
        .addOptionsModification(options -> options.enableClassStaticizer = false)
        .enableInliningAnnotations()
        .enableNoVerticalClassMergingAnnotations()
        .setMinApi(parameters.getApiLevel())
        .compile()
        .inspect(
            inspector -> {
              ClassSubject classSubject = inspector.clazz(TestClass.class);
              assertThat(classSubject, isPresent());

              MethodSubject mainSubject = classSubject.clinit();
              assertThat(mainSubject, isPresent());

              List<String> presentFields =
                  ImmutableList.of(
                      "directInstanceWithDirectFinalizer",
                      "directInstanceWithIndirectFinalizer",
                      "indirectInstanceWithDirectFinalizer",
                      "indirectInstanceWithIndirectFinalizer",
                      "otherIndirectInstanceWithoutFinalizer",
                      "arrayWithDirectFinalizer",
                      "arrayWithIndirectFinalizer",
                      "otherArrayInstanceWithoutFinalizer");
              for (String name : presentFields) {
                FieldSubject fieldSubject = classSubject.uniqueFieldWithName(name);
                assertThat(name, fieldSubject, isPresent());
                assertTrue(
                    mainSubject
                        .streamInstructions()
                        .filter(InstructionSubject::isStaticPut)
                        .map(InstructionSubject::getField)
                        .map(field -> field.name.toSourceString())
                        .anyMatch(fieldSubject.getFinalName()::equals));
              }

              List<String> absentFields =
                  ImmutableList.of(
                      "directInstanceWithoutFinalizer",
                      "otherDirectInstanceWithoutFinalizer",
                      "indirectInstanceWithoutFinalizer",
                      "arrayWithoutFinalizer");
              for (String name : absentFields) {
                assertThat(classSubject.uniqueFieldWithName(name), not(isPresent()));
              }
            })
        .run(parameters.getRuntime(), TestClass.class)
        .assertSuccessWithOutputLines("Hello world!");
  }

  static class TestClass {

    static A directInstanceWithDirectFinalizer = new A();
    static A directInstanceWithIndirectFinalizer = new B();
    static Object directInstanceWithoutFinalizer = new C();
    static Object otherDirectInstanceWithoutFinalizer = new Object();

    static A indirectInstanceWithDirectFinalizer = createA();
    static A indirectInstanceWithIndirectFinalizer = createB();
    static Object indirectInstanceWithoutFinalizer = createC();
    static Object otherIndirectInstanceWithoutFinalizer = createObject();

    static A[] arrayWithDirectFinalizer = new A[42];
    static A[] arrayWithIndirectFinalizer = new B[42];
    static Object[] arrayWithoutFinalizer = new C[42];
    static Object[] otherArrayInstanceWithoutFinalizer = new Object[42];

    public static void main(String[] args) {
      System.out.println("Hello world!");
    }

    @NeverInline
    static A createA() {
      return new A();
    }

    @NeverInline
    static B createB() {
      return new B();
    }

    @NeverInline
    static C createC() {
      return new C();
    }

    @NeverInline
    static Object createObject() {
      return new Object();
    }
  }

  @NoVerticalClassMerging
  static class A {

    @Override
    public void finalize() {
      System.out.println("Finalize!");
    }
  }

  static class B extends A {}

  static class C {}
}
