package eu.dnetlib.data.multimap;

import static org.junit.Assert.*;

import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.util.HashSet;
import java.util.Set;

import org.apache.commons.io.IOUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.junit.Test;

import com.google.gson.Gson;

public abstract class MultiMapTest {

	@Test
	public void Test(){
		String test,test2;
		test = postValue("k1", "v1");
		assertEquals(test, "true");
		
		test = postValue("k1", "v2");
		assertEquals(test, "true");
		
		test = listValues("k3");
		assertEquals(test, "");
		
		test = listValues("k1");
		assertEqualSets(test, "[\"v1\",\"v2\"]");
		
		test = postKeyAlias("k1", "k11");
		assertEquals(test, "true");
		
		test = getKeyAliases("k11");
		assertEqualSets(test, "[\"k11\",\"k1\"]");
		
		test = getKeyAliases("k1");
		assertEqualSets(test, "[\"k11\",\"k1\"]");
		
		test = listValues("k11");
		assertEqualSets(test, "[\"v2\",\"v1\"]");
		
		test = getValue("k1", 0);
		test2 = getValue("k11", 0);
		assertEquals(test, test2);
		
		test = getValue("k1", 1);
		test2 = getValue("k11", 1);
		assertEquals(test, test2);
		
		test = postValue("k11", "v3");
		assertEquals(test, "true");
		
		test = listValues("k1");
		assertEqualSets(test, "[\"v2\",\"v3\",\"v1\"]");
		
		test = removeKey("k1");
		assertEquals(test, "true");
		
		test = postValue("k1", "a1");
		assertEquals(test, "true");
		
		test = postValue("k1", "a2");
		assertEquals(test, "true");
		
		test = listValues("k1");
		assertEqualSets(test, "[\"a2\",\"a1\"]");
		
		test = listValues("k11");
		assertEqualSets(test, "[\"v2\",\"v3\",\"v1\"]");
		
		test = flushValues("k11");
		assertEquals(test, "true");
		
		test = listValues("k1");
		assertEqualSets(test, "[\"a2\",\"a1\"]");
		
		test = postValue("k11","v5");
		assertEquals(test, "true");
		
		test = postValue("k11", "v6");
		assertEquals(test, "true");
		
		test = removeKey("k1");
		assertEquals(test, "true");
		
		test = listValues("k11");
		assertEqualSets(test, "[\"v5\",\"v6\"]");
		
	}

	private void assertEqualSets(String test, String json) {
		Set<String> set1 = new Gson().fromJson(test, HashSet.class);
		Set<String> set2 = new Gson().fromJson(json, HashSet.class);
		assertEquals(set1, set2);
	}
	
	public String postKeyAlias(String key, String alias) {
		String URL = "http://localhost:8280/app/services/rest/multimap/keys/{key}/{alias}";
		HttpClient client = new DefaultHttpClient();

		HttpPost request = new HttpPost(URL.replace("{key}", key).replace("{alias}", alias));
		try {
			HttpResponse response = client.execute(request);
			HttpEntity entity = response.getEntity();
			InputStream inputStream = entity.getContent();
			StringWriter writer = new StringWriter();
			IOUtils.copy(inputStream, writer, null);
			return writer.toString();
		} catch (ClientProtocolException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	
	public String postValue(String key, String value) {
		String URL = "http://localhost:8280/app/services/rest/multimap/values/{key}";
		HttpClient client = new DefaultHttpClient();

		HttpPost request = new HttpPost(URL.replace("{key}", key));
		request.setHeader("Content-Type", "application/json");
		try {
			request.setEntity(new StringEntity(value));
			HttpResponse response = client.execute(request);
			HttpEntity entity = response.getEntity();
			InputStream inputStream = entity.getContent();
			StringWriter writer = new StringWriter();
			IOUtils.copy(inputStream, writer, null);
			return writer.toString();
		} catch (ClientProtocolException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return null;
	}
	
	public String flushValues(String key){
		String URL = "http://localhost:8280/app/services/rest/multimap/values/{key}";
		HttpClient client = new DefaultHttpClient();

		HttpDelete request = new HttpDelete(URL.replace("{key}", key));
		try {
			HttpResponse response = client.execute(request);
			HttpEntity entity = response.getEntity();
			InputStream inputStream = entity.getContent();
			StringWriter writer = new StringWriter();
			IOUtils.copy(inputStream, writer, null);
			return writer.toString();
		} catch (ClientProtocolException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return null;
	}
	
	public String removeKey(String key){
		String URL = "http://localhost:8280/app/services/rest/multimap/keys/{key}";
		HttpClient client = new DefaultHttpClient();

		HttpDelete request = new HttpDelete(URL.replace("{key}", key));
		try {
			HttpResponse response = client.execute(request);
			HttpEntity entity = response.getEntity();
			InputStream inputStream = entity.getContent();
			StringWriter writer = new StringWriter();
			IOUtils.copy(inputStream, writer, null);
			return writer.toString();
		} catch (ClientProtocolException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return null;
	}
	
	public String listValues(String key){
		String URL = "http://localhost:8280/app/services/rest/multimap/values/{key}";
		HttpClient client = new DefaultHttpClient();

		HttpGet request = new HttpGet(URL.replace("{key}", key));
		try {
			HttpResponse response = client.execute(request);
			HttpEntity entity = response.getEntity();
			InputStream inputStream = entity.getContent();
			StringWriter writer = new StringWriter();
			IOUtils.copy(inputStream, writer, null);
			return writer.toString();
		} catch (ClientProtocolException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	
	public String getValue(String key, int position){
		String URL = "http://localhost:8280/app/services/rest/multimap/values/{key}/{position}";
		HttpClient client = new DefaultHttpClient();

		HttpGet request = new HttpGet(URL.replace("{key}", key).replace("{position}", String.valueOf(position)));
		try {
			HttpResponse response = client.execute(request);
			HttpEntity entity = response.getEntity();
			InputStream inputStream = entity.getContent();
			StringWriter writer = new StringWriter();
			IOUtils.copy(inputStream, writer, null);
			return writer.toString();
		} catch (ClientProtocolException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	
	public String getKeyAliases(String key){
		String URL = "http://localhost:8280/app/services/rest/multimap/keys/{key}";
		HttpClient client = new DefaultHttpClient();

		HttpGet request = new HttpGet(URL.replace("{key}", key));
		try {
			HttpResponse response = client.execute(request);
			HttpEntity entity = response.getEntity();
			InputStream inputStream = entity.getContent();
			StringWriter writer = new StringWriter();
			IOUtils.copy(inputStream, writer, null);
			return writer.toString();
		} catch (ClientProtocolException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

}
