// 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 backport;

import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestRuntime.CfVm;
import com.android.tools.r8.desugar.backports.AbstractBackportTest;
import com.android.tools.r8.desugar.backports.IgnoreInvokes;
import com.android.tools.r8.utils.AndroidApiLevel;
import java.util.Set;
import org.hamcrest.CoreMatchers;
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 SetBackportJava9Test extends AbstractBackportTest {
  @Parameters(name = "{0}")
  public static Iterable<?> data() {
    return TestBase.getTestParameters()
        .withCfRuntimesStartingFromIncluding(CfVm.JDK9)
        .withDexRuntimes()
        .withAllApiLevelsAlsoForCf()
        .build();
  }

  public SetBackportJava9Test(TestParameters parameters) {
    super(parameters, Set.class, SetBackportJava9Main.class);
    // Note: None of the methods in this test exist in the latest android.jar. If/when they ship in
    // an actual API level, migrate these tests to SetBackportTest.

    // Available since API 1 and used to test created sets.
    ignoreInvokes("add");
    ignoreInvokes("contains");
    ignoreInvokes("size");

    // Set.of added in API 30.
    registerTarget(AndroidApiLevel.R, 21);
  }

  @Test
  public void desugaringApiLevelR() throws Exception {
    // TODO(b/154759404): This test should start to fail when testing on an Android R VM.
    // This has now been checked with S, when R testing is added check and remove this.
    if (parameters.getRuntime().isDex() && parameters.getApiLevel().isEqualTo(AndroidApiLevel.R)) {
      testForD8()
          .setMinApi(AndroidApiLevel.R)
          .addProgramClasses(MiniAssert.class, IgnoreInvokes.class)
          .addProgramClasses(SetBackportJava9Main.class)
          .setIncludeClassesChecksum(true)
          .compile()
          .run(parameters.getRuntime(), SetBackportJava9Main.class)
          .assertFailureWithErrorThatMatches(
              CoreMatchers.containsString("java.lang.NoSuchMethodError"));
    }
  }

  public static class SetBackportJava9Main {

    public static void main(String[] args) {
      testOf0();
      testOf1();
      testOf2();
      testOf10();
      testOfVarargs();
    }

    private static void testOf0() {
      Set<Object> ofObject = Set.of();
      assertEquals(0, ofObject.size());
      assertFalse(ofObject.contains(new Object()));
      assertMutationNotAllowed(ofObject);

      Set<Integer> ofInteger = Set.of();
      assertEquals(0, ofInteger.size());
      assertFalse(ofInteger.contains(0));
    }

    private static void testOf1() {
      Object anObject = new Object();
      Set<Object> ofObject = Set.of(anObject);
      assertEquals(1, ofObject.size());
      assertTrue(ofObject.contains(anObject));
      assertFalse(ofObject.contains(new Object()));
      assertMutationNotAllowed(ofObject);

      Set<Integer> ofInteger = Set.of(1);
      assertEquals(1, ofInteger.size());
      assertTrue(ofInteger.contains(1));
      assertFalse(ofInteger.contains(2));

      try {
        Set.of((Object) null);
        throw new AssertionError();
      } catch (NullPointerException expected) {
      }
    }

    private static void testOf2() {
      Object anObject0 = new Object();
      Object anObject1 = new Object();
      Set<Object> ofObject = Set.of(anObject0, anObject1);
      assertEquals(2, ofObject.size());
      assertTrue(ofObject.contains(anObject0));
      assertTrue(ofObject.contains(anObject1));
      assertFalse(ofObject.contains(new Object()));
      assertMutationNotAllowed(ofObject);

      Set<Integer> ofInteger = Set.of(1, 2);
      assertEquals(2, ofInteger.size());
      assertTrue(ofInteger.contains(1));
      assertTrue(ofInteger.contains(2));
      assertFalse(ofInteger.contains(3));

      Set<Object> ofMixed = Set.of(anObject0, 1);
      assertEquals(2, ofMixed.size());
      assertTrue(ofMixed.contains(anObject0));
      assertTrue(ofMixed.contains(1));
      assertFalse(ofMixed.contains(2));
      assertFalse(ofMixed.contains(anObject1));
      assertMutationNotAllowed(ofMixed);

      try {
        Set.of(1, null);
        throw new AssertionError();
      } catch (NullPointerException expected) {
      }

      try {
        Set.of(1, 1);
        throw new AssertionError();
      } catch (IllegalArgumentException expected) {
        assertEquals("duplicate element: 1", expected.getMessage());
      }
    }

    private static void testOf10() {
      Object anObject0 = new Object();
      Object anObject6 = new Object();
      Object anObject9 = new Object();
      Set<Object> ofObject =
          Set.of(
              anObject0,
              new Object(),
              new Object(),
              new Object(),
              new Object(),
              new Object(),
              anObject6,
              new Object(),
              new Object(),
              anObject9);
      assertEquals(10, ofObject.size());
      assertTrue(ofObject.contains(anObject0));
      assertTrue(ofObject.contains(anObject6));
      assertTrue(ofObject.contains(anObject9));
      assertFalse(ofObject.contains(new Object()));
      assertMutationNotAllowed(ofObject);

      Set<Integer> ofInteger = Set.of(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
      assertEquals(10, ofInteger.size());
      assertTrue(ofInteger.contains(0));
      assertTrue(ofInteger.contains(6));
      assertTrue(ofInteger.contains(9));
      assertFalse(ofInteger.contains(10));

      Set<Object> ofMixed = Set.of(0, 1, 2, 3, 4, 5, 6, 7, 8, anObject9);
      assertEquals(10, ofMixed.size());
      assertTrue(ofMixed.contains(0));
      assertTrue(ofMixed.contains(6));
      assertTrue(ofMixed.contains(anObject9));
      assertFalse(ofMixed.contains(anObject0));
      assertMutationNotAllowed(ofMixed);

      try {
        Set.of(0, 1, 2, 3, 4, 5, 6, 7, 8, null);
        throw new AssertionError();
      } catch (NullPointerException expected) {
      }

      try {
        Set.of(0, 1, 2, 3, 4, 5, 6, 7, 8, 0);
        throw new AssertionError();
      } catch (IllegalArgumentException expected) {
        assertEquals("duplicate element: 0", expected.getMessage());
      }
    }

    private static void testOfVarargs() {
      Object anObject0 = new Object();
      Object anObject6 = new Object();
      Object anObject10 = new Object();
      Set<Object> ofObject =
          Set.of(
              anObject0,
              new Object(),
              new Object(),
              new Object(),
              new Object(),
              new Object(),
              anObject6,
              new Object(),
              new Object(),
              new Object(),
              anObject10);
      assertEquals(11, ofObject.size());
      assertTrue(ofObject.contains(anObject0));
      assertTrue(ofObject.contains(anObject6));
      assertTrue(ofObject.contains(anObject10));
      assertFalse(ofObject.contains(new Object()));
      assertMutationNotAllowed(ofObject);

      Set<Integer> ofInteger = Set.of(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
      assertEquals(11, ofInteger.size());
      assertTrue(ofInteger.contains(0));
      assertTrue(ofInteger.contains(6));
      assertTrue(ofInteger.contains(10));
      assertFalse(ofInteger.contains(11));

      Set<Object> ofMixed = Set.of(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, anObject10);
      assertEquals(11, ofMixed.size());
      assertTrue(ofMixed.contains(0));
      assertTrue(ofMixed.contains(6));
      assertTrue(ofMixed.contains(anObject10));
      assertFalse(ofMixed.contains(10));
      assertFalse(ofMixed.contains(anObject0));
      assertMutationNotAllowed(ofMixed);

      // Ensure the supplied mutable array is not used directly since it is mutable.
      Object[] mutableArray = {anObject0};
      Set<Object> ofMutableArray = Set.of(mutableArray);
      mutableArray[0] = anObject10;
      assertTrue(ofMutableArray.contains(anObject0));
      assertFalse(ofMutableArray.contains(anObject10));

      try {
        Set.of(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, null);
        throw new AssertionError();
      } catch (NullPointerException expected) {
      }

      try {
        Set.of(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0);
        throw new AssertionError();
      } catch (IllegalArgumentException expected) {
        assertEquals("duplicate element: 0", expected.getMessage());
      }
    }

    private static void assertMutationNotAllowed(Set<Object> ofObject) {
      try {
        ofObject.add(new Object());
        throw new AssertionError();
      } catch (UnsupportedOperationException expected) {
      }
    }

    private static void assertTrue(boolean value) {
      if (!value) {
        throw new AssertionError("Expected <true> but was <false>");
      }
    }

    private static void assertFalse(boolean value) {
      if (value) {
        throw new AssertionError("Expected <false> but was <true>");
      }
    }

    private static void assertEquals(Object expected, Object actual) {
      if (expected != actual && !expected.equals(actual)) {
        throw new AssertionError("Expected <" + expected + "> but was <" + actual + ">");
      }
    }
  }
}
