/*
 * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/**
 * @test
 * @bug 8048209
 * @summary Check that Collections.synchronizedNavigableSet().tailSet() is using
 * the same lock object as it's source.
 * @run testng SyncSubMutexes
 */
import java.lang.reflect.Field;
import java.util.*;
import java.util.Set;
import java.util.Arrays;

import org.testng.annotations.Test;
import org.testng.annotations.DataProvider;
import static org.testng.Assert.assertSame;

public class SyncSubMutexes {

    @Test(dataProvider = "Collections")
    public void testCollections(Collection<String> instance) {
        // nothing to test, no subset methods
    }

    @Test(dataProvider = "Lists")
    public void testLists(List<String> instance) {
         assertSame(getSyncCollectionMutex(instance.subList(0, 1)), getSyncCollectionMutex(instance));
    }

    @Test(dataProvider = "Sets")
    public void testSets(Set<String> instance) {
        // nothing to test, no subset methods

    }

    @Test(dataProvider = "SortedSets")
    public void testSortedSets(SortedSet<String> instance) {
         assertSame(getSyncCollectionMutex(instance.headSet("Echo")), getSyncCollectionMutex(instance));
         assertSame(getSyncCollectionMutex(instance.tailSet("Charlie")), getSyncCollectionMutex(instance));
         assertSame(getSyncCollectionMutex(instance.subSet("Charlie", "Echo")), getSyncCollectionMutex(instance));

    }

    @Test(dataProvider = "NavigableSets")
    public void testNavigableSets(NavigableSet<String> instance) {
         assertSame(getSyncCollectionMutex(instance.descendingSet()), getSyncCollectionMutex(instance));
         assertSame(getSyncCollectionMutex(instance.headSet("Echo")), getSyncCollectionMutex(instance));
         assertSame(getSyncCollectionMutex(instance.headSet("Echo", true)), getSyncCollectionMutex(instance));
         assertSame(getSyncCollectionMutex(instance.tailSet("Charlie")), getSyncCollectionMutex(instance));
         assertSame(getSyncCollectionMutex(instance.tailSet("Charlie", true)), getSyncCollectionMutex(instance));
         assertSame(getSyncCollectionMutex(instance.subSet("Charlie", "Echo")), getSyncCollectionMutex(instance));
         assertSame(getSyncCollectionMutex(instance.subSet("Charlie", true, "Echo", true)), getSyncCollectionMutex(instance));
    }

    @Test(dataProvider = "Maps")
    public void testMaps(Map<String, String> instance) {
         assertSame(getSyncCollectionMutex(instance.entrySet()), getSyncMapMutex(instance));
         assertSame(getSyncCollectionMutex(instance.keySet()), getSyncMapMutex(instance));
         assertSame(getSyncCollectionMutex(instance.values()), getSyncMapMutex(instance));
    }

    @Test(dataProvider = "SortedMaps")
    public void testSortedMaps(SortedMap<String, String> instance) {
         assertSame(getSyncCollectionMutex(instance.entrySet()), getSyncMapMutex(instance));
         assertSame(getSyncCollectionMutex(instance.keySet()), getSyncMapMutex(instance));
         assertSame(getSyncCollectionMutex(instance.values()), getSyncMapMutex(instance));
         assertSame(getSyncMapMutex(instance.headMap("Echo")), getSyncMapMutex(instance));
         assertSame(getSyncMapMutex(instance.tailMap("Charlie")), getSyncMapMutex(instance));
         assertSame(getSyncMapMutex(instance.subMap("Charlie", "Echo")), getSyncMapMutex(instance));
    }

    @Test(dataProvider = "NavigableMaps")
    public void testNavigableMaps(NavigableMap<String, String> instance) {
         assertSame(getSyncMapMutex(instance.descendingMap()), getSyncMapMutex(instance));
         assertSame(getSyncCollectionMutex(instance.entrySet()), getSyncMapMutex(instance));
         assertSame(getSyncCollectionMutex(instance.keySet()), getSyncMapMutex(instance));
         assertSame(getSyncCollectionMutex(instance.descendingKeySet()), getSyncMapMutex(instance));
         assertSame(getSyncCollectionMutex(instance.values()), getSyncMapMutex(instance));
         assertSame(getSyncMapMutex(instance.headMap("Echo")), getSyncMapMutex(instance));
         assertSame(getSyncMapMutex(instance.headMap("Echo", true)), getSyncMapMutex(instance));
         assertSame(getSyncMapMutex(instance.tailMap("Charlie")), getSyncMapMutex(instance));
         assertSame(getSyncMapMutex(instance.tailMap("Charlie", true)), getSyncMapMutex(instance));
         assertSame(getSyncMapMutex(instance.subMap("Charlie", true, "Echo", true)), getSyncMapMutex(instance));
         assertSame(getSyncMapMutex(instance.subMap("Charlie", true, "Echo", true)), getSyncMapMutex(instance));
    }

    @DataProvider(name = "Collections", parallel = true)
    public static Iterator<Object[]> collectionProvider() {
        return makeCollections().iterator();
    }

    @DataProvider(name = "Lists", parallel = true)
    public static Iterator<Object[]> listProvider() {
        return makeLists().iterator();
    }

    @DataProvider(name = "Sets", parallel = true)
    public static Iterator<Object[]> setProvider() {
        return makeSets().iterator();
    }

    @DataProvider(name = "SortedSets", parallel = true)
    public static Iterator<Object[]> sortedsetProvider() {
        return makeSortedSets().iterator();
    }

    @DataProvider(name = "NavigableSets", parallel = true)
    public static Iterator<Object[]> navigablesetProvider() {
        return makeNavigableSets().iterator();
    }

    @DataProvider(name = "Maps", parallel = true)
    public static Iterator<Object[]> mapProvider() {
        return makeMaps().iterator();
    }

    @DataProvider(name = "SortedMaps", parallel = true)
    public static Iterator<Object[]> sortedmapProvider() {
        return makeSortedMaps().iterator();
    }

    @DataProvider(name = "NavigableMaps", parallel = true)
    public static Iterator<Object[]> navigablemapProvider() {
        return makeNavigableMaps().iterator();
    }

    private static final Collection<String> BASE_COLLECTION = Collections.unmodifiableCollection(
            Arrays.asList("Alpha", "Bravo", "Charlie", "Delta", "Echo", "Foxtrot", "Golf")
    );
    private static final Map<String, String> BASE_MAP;

    static {
        Map<String, String> map = new HashMap<>();
        for(String each : BASE_COLLECTION) {
            map.put(each, "*" + each + "*");
        }
        BASE_MAP = Collections.unmodifiableMap(map);
    }

    public static Collection<Object[]> makeCollections() {
        Collection<Object[]> instances = new ArrayList<>();
        instances.add(new Object[] {Collections.synchronizedCollection(new ArrayList<>(BASE_COLLECTION))});
        instances.addAll(makeLists());

        return instances;
    }

    public static Collection<Object[]> makeLists() {
        Collection<Object[]> instances = new ArrayList<>();
        instances.add(new Object[] {Collections.synchronizedList(new ArrayList<>(BASE_COLLECTION))});
        instances.add(new Object[] {Collections.synchronizedList(new ArrayList<>(BASE_COLLECTION)).subList(1, 2)});

        return instances;
    }

     public static Collection<Object[]> makeSets() {
        Collection<Object[]> instances = new ArrayList<>();

        instances.add(new Object[] {Collections.synchronizedSet(new TreeSet<>(BASE_COLLECTION))});
        instances.addAll(makeSortedSets());
        return instances;
     }

    public static Collection<Object[]> makeSortedSets() {
        Collection<Object[]> instances = new ArrayList<>();
        instances.add(new Object[] {Collections.synchronizedSortedSet(new TreeSet<>(BASE_COLLECTION))});
        instances.add(new Object[] {Collections.synchronizedSortedSet(new TreeSet<>(BASE_COLLECTION)).headSet("Foxtrot")});
        instances.add(new Object[] {Collections.synchronizedSortedSet(new TreeSet<>(BASE_COLLECTION)).tailSet("Bravo")});
        instances.add(new Object[] {Collections.synchronizedSortedSet(new TreeSet<>(BASE_COLLECTION)).subSet("Bravo", "Foxtrot")});
        instances.addAll(makeNavigableSets());

        return instances;
     }

    public static Collection<Object[]> makeNavigableSets() {
        Collection<Object[]> instances = new ArrayList<>();

        instances.add(new Object[] {Collections.synchronizedNavigableSet(new TreeSet<>(BASE_COLLECTION))});
        instances.add(new Object[] {Collections.synchronizedNavigableSet(new TreeSet<>(BASE_COLLECTION)).descendingSet().descendingSet()});
        instances.add(new Object[] {Collections.synchronizedNavigableSet(new TreeSet<>(BASE_COLLECTION)).headSet("Foxtrot")});
        instances.add(new Object[] {Collections.synchronizedNavigableSet(new TreeSet<>(BASE_COLLECTION)).headSet("Foxtrot", true)});
        instances.add(new Object[] {Collections.synchronizedNavigableSet(new TreeSet<>(BASE_COLLECTION)).tailSet("Bravo")});
        instances.add(new Object[] {Collections.synchronizedNavigableSet(new TreeSet<>(BASE_COLLECTION)).tailSet("Bravo", true)});
        instances.add(new Object[] {Collections.synchronizedNavigableSet(new TreeSet<>(BASE_COLLECTION)).subSet("Bravo", "Foxtrot")});
        instances.add(new Object[] {Collections.synchronizedNavigableSet(new TreeSet<>(BASE_COLLECTION)).subSet("Bravo", true, "Foxtrot", true)});

        return instances;
    }

    public static Collection<Object[]> makeMaps() {
        Collection<Object[]> instances = new ArrayList<>();

        instances.add(new Object[] {Collections.synchronizedMap(new HashMap<>(BASE_MAP))});
        instances.addAll(makeSortedMaps());

        return instances;
    }

    public static Collection<Object[]> makeSortedMaps() {
        Collection<Object[]> instances = new ArrayList<>();

        instances.add(new Object[] {Collections.synchronizedSortedMap(new TreeMap<>(BASE_MAP))});
        instances.add(new Object[] {Collections.synchronizedSortedMap(new TreeMap<>(BASE_MAP)).headMap("Foxtrot")});
        instances.add(new Object[] {Collections.synchronizedSortedMap(new TreeMap<>(BASE_MAP)).tailMap("Bravo")});
        instances.add(new Object[] {Collections.synchronizedSortedMap(new TreeMap<>(BASE_MAP)).subMap("Bravo", "Foxtrot")});
        instances.addAll(makeNavigableMaps());

        return instances;
    }

    public static Collection<Object[]> makeNavigableMaps() {
        Collection<Object[]> instances = new ArrayList<>();

        instances.add(new Object[] {Collections.synchronizedNavigableMap(new TreeMap<>(BASE_MAP))});
        instances.add(new Object[] {Collections.synchronizedNavigableMap(new TreeMap<>(BASE_MAP).descendingMap().descendingMap())});
        instances.add(new Object[] {Collections.synchronizedNavigableMap(new TreeMap<>(BASE_MAP)).headMap("Foxtrot")});
        instances.add(new Object[] {Collections.synchronizedNavigableMap(new TreeMap<>(BASE_MAP)).headMap("Foxtrot", true)});
        instances.add(new Object[] {Collections.synchronizedNavigableMap(new TreeMap<>(BASE_MAP)).tailMap("Bravo")});
        instances.add(new Object[] {Collections.synchronizedNavigableMap(new TreeMap<>(BASE_MAP)).tailMap("Bravo", true)});
        instances.add(new Object[] {Collections.synchronizedNavigableMap(new TreeMap<>(BASE_MAP)).subMap("Bravo", "Foxtrot")});
        instances.add(new Object[] {Collections.synchronizedNavigableMap(new TreeMap<>(BASE_MAP)).subMap("Bravo", true, "Foxtrot", true)});

        return instances;
    }

    private static Object getSyncCollectionMutex(Collection<?> from) {
        try {
            Class<?> synchronizedCollectionClazz = Class.forName("java.util.Collections$SynchronizedCollection");
            Field f = synchronizedCollectionClazz.getDeclaredField("mutex");
            f.setAccessible(true);
            return f.get(from);
        } catch ( ClassNotFoundException | NoSuchFieldException | IllegalAccessException e) {
            throw new RuntimeException("Unable to get mutex field.", e);
        }
    }

    private static Object getSyncMapMutex(Map<?,?> from) {
        try {
            Class<?> synchronizedMapClazz = Class.forName("java.util.Collections$SynchronizedMap");
            Field f = synchronizedMapClazz.getDeclaredField("mutex");
            f.setAccessible(true);
            return f.get(from);
        } catch ( ClassNotFoundException | NoSuchFieldException | IllegalAccessException e) {
            throw new RuntimeException("Unable to get mutex field.", e);
        }
    }

}
