/*******************************************************************************
 * Copyright (c) 2017 Universite de Technologie de Belfort-Montbeliard (http://www.utbm.fr) and others.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * SPDX-License-Identifier: EPL-2.0
 *******************************************************************************/
package org.eclipse.xtext.xbase.tests.lib;

import static org.eclipse.xtext.xbase.lib.MapExtensions.*;
import static org.junit.Assert.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.Map.Entry;

import com.google.common.collect.Maps;
import com.google.common.collect.testing.MapTestSuiteBuilder;
import com.google.common.collect.testing.TestStringMapGenerator;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
import com.google.common.collect.testing.features.MapFeature;
import junit.framework.TestSuite;
import org.eclipse.xtext.xbase.lib.Pair;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;

import org.eclipse.xtext.xbase.lib.internal.UnmodifiableMergingMapView;

/**
 * @author Stephane Galland - Initial contribution and API
 * @since 2.15
 */
@SuppressWarnings("all")
@RunWith(Suite.class)
@SuiteClasses({
	MapExtensionsTest.ManualTest.class,
	MapExtensionsTest.GuavaTest.class,
})
public class MapExtensionsTest {

	public static class GuavaTest {
		public static TestSuite suite() {
			return MapTestSuiteBuilder
					// The create method is called with an array of elements
					// that should populate the collection.
					.using(new TestStringMapGenerator() {
						@Override
						protected Map<String, String> create(Entry<String, String>[] source) {
							Map<String, String> left = Maps.newHashMap();
							Map<String, String> right = Maps.newHashMap();
							for(int i = 0; i < source.length; i++) {
								Entry<String, String> entry = source[i];
								if (right.containsKey(entry.getKey())) {
									left.put(entry.getKey(), right.get(entry.getKey()));
									right.put(entry.getKey(), entry.getValue());
								} else if (i % 2 != 0) {
									left.put(entry.getKey(), entry.getValue());	
								} else {
									right.put(entry.getKey(), entry.getValue());
									if (i % 4 != 0) {
										left.put(entry.getKey(), "will be ignored");
									}
								}
							}
							return new UnmodifiableMergingMapView(left, right);
						}
					}).named("Guava-based UnmodifiableMergingMapView tests")
					.withFeatures(
							MapFeature.ALLOWS_NULL_KEYS,
							MapFeature.ALLOWS_NULL_VALUES,
							MapFeature.ALLOWS_ANY_NULL_QUERIES,
							MapFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION,
							CollectionFeature.ALLOWS_NULL_QUERIES,
							CollectionFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION,
							CollectionSize.ANY)
					.createTestSuite();
		}
	}

	public static class ManualTest {

		private Map<String, String> map;
		private String key1;
		private String key2;
		private String value1;
		private String value2;
	
		@Before
		public void setUp() {
			this.map = new HashMap<String, String>();
			this.key1 = "k1"; //$NON-NLS-1$
			this.key2 = "k2"; //$NON-NLS-1$
			this.value1 = UUID.randomUUID().toString();
			this.value2 = UUID.randomUUID().toString();
			this.map.put(this.key1, this.value1);
			this.map.put(this.key2, this.value2);
		}
	
		@After
		public void tearDown() {
			this.key1 = this.value1 = null;
			this.key2 = this.value2 = null;
			this.map = null;
		}
	
		@Test
		public void operator_add_MapPair_0() {
			String v = UUID.randomUUID().toString();
			String o;
	
			o = operator_add(this.map, new Pair<String, String>("k3", v));
			assertNull(o);
			assertEquals(3, this.map.size());
			assertEquals(this.value1, this.map.get("k1"));
			assertEquals(this.value2, this.map.get("k2"));
			assertEquals(v, this.map.get("k3"));
		}
	
		@Test
		public void operator_add_MapPair_1() {
			String v = UUID.randomUUID().toString();
			String o;
	
			o = operator_add(this.map, new Pair<String, String>("k2", v));
			assertEquals(this.value2, o);
			assertEquals(2, this.map.size());
			assertEquals(this.value1, this.map.get("k1"));
			assertEquals(v, this.map.get("k2"));
		}
	
		@Test
		public void operator_remove_MapPair_0() {
			String v = UUID.randomUUID().toString();
			boolean o;
	
			o = operator_remove(this.map, new Pair<String, String>("k3", v));
			assertFalse(o);
			assertEquals(2, this.map.size());
			assertEquals(this.value1, this.map.get("k1"));
			assertEquals(this.value2, this.map.get("k2"));
		}
	
		@Test
		public void operator_remove_MapPair_1() {
			String v = UUID.randomUUID().toString();
			boolean o;
	
			o = operator_remove(this.map, new Pair<String, String>("k2", v));
			assertFalse(o);
			assertEquals(2, this.map.size());
			assertEquals(this.value1, this.map.get("k1"));
			assertEquals(this.value2, this.map.get("k2"));
		}
	
		@Test
		public void operator_remove_MapPair_2() {
			String v = UUID.randomUUID().toString();
			boolean o;
	
			o = operator_remove(this.map, new Pair<String, String>("k2", new String(this.value2)));
			assertTrue(o);
			assertEquals(1, this.map.size());
			assertEquals(this.value1, this.map.get("k1"));
			assertNull(this.map.get("k2"));
		}
	
		@Test
		public void operator_plus_MapPair_0() {
			String v = UUID.randomUUID().toString();
			Map<String, String> o;
	
			o = operator_plus(this.map, new Pair<String, String>("k3", v));
			assertNotNull(o);
			assertNotSame(this.map, o);
			assertEquals(2, this.map.size());
			assertEquals(this.value1, this.map.get("k1"));
			assertEquals(this.value2, this.map.get("k2"));
			assertEquals(3, o.size());
			assertEquals(this.value1, o.get("k1"));
			assertEquals(this.value2, o.get("k2"));
			assertEquals(v, o.get("k3"));
		}
	
		@Test
		public void operator_plus_MapPair_1() {
			String v = UUID.randomUUID().toString();
			Map<String, String> o = operator_plus(this.map, new Pair<String, String>("k2", v));
			assertNotNull(o);
			assertNotSame(this.map, o);
			assertEquals(2, this.map.size());
			assertEquals(this.value1, this.map.get("k1"));
			assertEquals(this.value2, this.map.get("k2"));
			assertNull(this.map.get("k3"));
			assertEquals(2, o.size());
			assertEquals(this.value1, o.get("k1"));
			assertEquals(v, o.get("k2"));
			assertNull(o.get("k3"));
		}
	
		@Test
		public void operator_minus_MapPair_0() {
			String v = UUID.randomUUID().toString();
			Map<String, String> o;
	
			o = operator_minus(this.map, new Pair<String, String>("k3", v));
	
			assertNotNull(o);
			assertNotSame(this.map, o);
			
			assertEquals(2, this.map.size());
			assertEquals(this.value1, this.map.get("k1"));
			assertEquals(this.value2, this.map.get("k2"));
			assertNull(this.map.get("k3"));
			
			assertEquals(2, o.size());
			assertEquals(this.value1, o.get("k1"));
			assertEquals(this.value2, o.get("k2"));
			assertNull(o.get("k3"));
		}
	
		@Test
		public void operator_minus_MapPair_1() {
			String v = UUID.randomUUID().toString();
			Map<String, String> o = operator_minus(this.map, new Pair<String, String>("k2", v));
			
			assertNotNull(o);
			assertNotSame(this.map, o);
			
			assertEquals(2, this.map.size());
			assertEquals(this.value1, this.map.get("k1"));
			assertEquals(this.value2, this.map.get("k2"));
			assertNull(this.map.get("k3"));
			
			assertEquals(2, o.size());
			assertEquals(this.value1, o.get("k1"));
			assertEquals(this.value2, o.get("k2"));
			assertNull(o.get("k3"));
		}
	
		@Test
		public void operator_minus_MapPair_2() {
			String v = UUID.randomUUID().toString();
			Map<String, String> o = operator_minus(this.map, new Pair<String, String>("k2", new String(this.value2)));
			
			assertNotNull(o);
			assertNotSame(this.map, o);
			
			assertEquals(2, this.map.size());
			assertEquals(this.value1, this.map.get("k1"));
			assertEquals(this.value2, this.map.get("k2"));
			assertNull(this.map.get("k3"));
			
			assertEquals(1, o.size());
			assertEquals(this.value1, o.get("k1"));
			assertNull(o.get("k2"));
			assertNull(o.get("k3"));
		}
	
		@Test
		public void operator_plus_MapMap_0() {
			String v1 = UUID.randomUUID().toString();
			String v2 = UUID.randomUUID().toString();
			String v3 = UUID.randomUUID().toString();
			Map<String, String> o;
	
			Map<String, String> tmp = new HashMap<String, String>();
			tmp.put("k3", v1);
			tmp.put("k4", v2);
			tmp.put("k5", v3);
	
			o = operator_plus(this.map, tmp);
			assertNotNull(o);
			assertNotSame(this.map, o);
			assertNotSame(tmp, o);
			assertEquals(2, this.map.size());
			assertEquals(this.value1, this.map.get("k1"));
			assertEquals(this.value2, this.map.get("k2"));
			assertEquals(3, tmp.size());
			assertEquals(v1, tmp.get("k3"));
			assertEquals(v2, tmp.get("k4"));
			assertEquals(v3, tmp.get("k5"));
			assertEquals(5, o.size());
			assertEquals(this.value1, o.get("k1"));
			assertEquals(this.value2, o.get("k2"));
			assertEquals(v1, o.get("k3"));
			assertEquals(v2, o.get("k4"));
			assertEquals(v3, o.get("k5"));
		}
	
		@Test
		public void operator_plus_MapMap_1() {
			String v1 = UUID.randomUUID().toString();
			String v2 = UUID.randomUUID().toString();
			String v3 = UUID.randomUUID().toString();
			Map<String, String> o;
	
			Map<String, String> tmp = new HashMap<String, String>();
			tmp.put("k3", v1);
			tmp.put("k4", v2);
			tmp.put("k5", v3);
	
			o = operator_plus(tmp, this.map);
			assertNotNull(o);
			assertNotSame(this.map, o);
			assertNotSame(tmp, o);
			assertEquals(2, this.map.size());
			assertEquals(this.value1, this.map.get("k1"));
			assertEquals(this.value2, this.map.get("k2"));
			assertEquals(3, tmp.size());
			assertEquals(v1, tmp.get("k3"));
			assertEquals(v2, tmp.get("k4"));
			assertEquals(v3, tmp.get("k5"));
			assertEquals(5, o.size());
			assertEquals(this.value1, o.get("k1"));
			assertEquals(this.value2, o.get("k2"));
			assertEquals(v1, o.get("k3"));
			assertEquals(v2, o.get("k4"));
			assertEquals(v3, o.get("k5"));
		}
	
		@Test
		public void operator_plus_MapMap_2() {
			String v1 = UUID.randomUUID().toString();
			String v2 = UUID.randomUUID().toString();
			String v3 = UUID.randomUUID().toString();
			Map<String, String> o;
	
			Map<String, String> tmp = new HashMap<String, String>();
			tmp.put("k3", v1);
			tmp.put("k1", v2);
			tmp.put("k5", v3);
	
			o = operator_plus(this.map, tmp);
			assertNotNull(o);
			assertEquals(4, o.size());
			assertEquals(v2, o.get("k1"));
			assertEquals(this.value2, o.get("k2"));
			assertEquals(v1, o.get("k3"));
			assertNull(o.get("k4"));
			assertEquals(v3, o.get("k5"));
		}
	
		@Test
		public void operator_plus_MapMap_3() {
			String v1 = UUID.randomUUID().toString();
			String v2 = UUID.randomUUID().toString();
			String v3 = UUID.randomUUID().toString();
			Map<String, String> o;
	
			Map<String, String> tmp = new HashMap<String, String>();
			tmp.put("k3", v1);
			tmp.put("k1", v2);
			tmp.put("k5", v3);
	
			o = operator_plus(tmp, this.map);
			assertNotNull(o);
			assertEquals(4, o.size());
			assertEquals(this.value1, o.get("k1"));
			assertEquals(this.value2, o.get("k2"));
			assertEquals(v1, o.get("k3"));
			assertNull(o.get("k4"));
			assertEquals(v3, o.get("k5"));
		}
	
		@Test
		public void operator_remove_MapK_0() {
			String o = operator_remove(this.map, "k0");
			assertEquals(2, this.map.size());
			assertEquals(this.value1, this.map.get("k1"));
			assertEquals(this.value2, this.map.get("k2"));
			assertNull(o);
		}
	
		@Test
		public void operator_remove_MapK_1() {
			String o = operator_remove(this.map, "k1");
			assertEquals(1, this.map.size());
			assertNull(this.map.get("k1"));
			assertEquals(this.value2, this.map.get("k2"));
			assertEquals(this.value1, o);
		}
	
		@Test
		public void operator_remove_MapK_2() {
			String o = operator_remove(this.map, "k2");
			assertEquals(1, this.map.size());
			assertEquals(this.value1, this.map.get("k1"));
			assertNull(this.map.get("k2"));
			assertEquals(this.value2, o);
		}
	
		@Test
		public void operator_remove_MapK_3() {
			String o1 = operator_remove(this.map, "k2");
			String o2 = operator_remove(this.map, "k1");
			assertEquals(0, this.map.size());
			assertNull(this.map.get("k1"));
			assertNull(this.map.get("k2"));
			assertEquals(this.value2, o1);
			assertEquals(this.value1, o2);
		}
	
		@Test
		public void operator_remove_MapIterable() {
			List<String> m = new ArrayList<String>();
			m.add("k0");
			m.add("k1");
			operator_remove(this.map, m);
			assertEquals(1, this.map.size());
			assertNull(this.map.get("k1"));
			assertEquals(this.value2, this.map.get("k2"));
		}
	
		@Test
		public void operator_minus_MapK_0() {
			Map<String, String> o = operator_minus(this.map, "k0");
			assertEquals(2, this.map.size());
			assertEquals(this.value1, this.map.get("k1"));
			assertEquals(this.value2, this.map.get("k2"));
			assertNotNull(o);
			assertNotSame(this.map, o);
			assertEquals(2, o.size());
			assertEquals(this.value1, o.get("k1"));
			assertEquals(this.value2, o.get("k2"));
		}
	
		@Test
		public void operator_minus_MapK_1() {
			Map<String, String> o = operator_minus(this.map, "k2");
			assertEquals(2, this.map.size());
			assertEquals(this.value1, this.map.get("k1"));
			assertEquals(this.value2, this.map.get("k2"));
			assertNotNull(o);
			assertNotSame(this.map, o);
			assertEquals(1, o.size());
			assertEquals(this.value1, o.get("k1"));
			assertNull(o.get("k2"));
		}
	
		@Test
		public void operator_minus_MapK_2() {
			Map<String, String> o1 = operator_minus(this.map, "k2");
			Map<String, String> o2 = operator_minus(o1, "k1");
			assertEquals(2, this.map.size());
			assertEquals(this.value1, this.map.get("k1"));
			assertEquals(this.value2, this.map.get("k2"));
			assertNotNull(o1);
			assertNotSame(this.map, o1);
			assertEquals(1, o1.size());
			assertEquals(this.value1, o1.get("k1"));
			assertNull(o1.get("k2"));
			assertNotNull(o2);
			assertNotSame(this.map, o2);
			assertEquals(0, o2.size());
			assertNull(o2.get("k1"));
			assertNull(o2.get("k2"));
		}

	}

}

