package eu.dnetlib.enabling.aas.ctx.tools;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;

import java.util.ArrayList;
import java.util.List;

import org.junit.Test;

import eu.dnetlib.enabling.aas.ctx.tools.CodingContext;
import eu.dnetlib.enabling.aas.ctx.tools.DecodingResponse;
import eu.dnetlib.enabling.aas.ctx.tools.ICtxRecoder;
import eu.dnetlib.enabling.aas.ctx.tools.V1ContextRecoder;


public class V1ContextRecoderTest {

	@Test
	public void testValidSecCtxChain() {
		V1ContextRecoder recoder = new V1ContextRecoder();
		String secCtxChain = "prof0|secCtx0;prof1|secCtx1;prof2|secCtx2;prof3|secCtx3";
		DecodingResponse[] responses = resolveResponses(secCtxChain, recoder);
		assertNotNull(responses);
		assertEquals(4, responses.length);
		for (int i=0; i<responses.length; i++) {
			assertEquals("secCtx"+i, responses[i].secCtxId);
			assertEquals("prof"+i, responses[i].resourceId);
		}
		
		String outputSecCtxChain = null;
		for (int i=0; i<responses.length; i++) {
			CodingContext ctx = new CodingContext();
			ctx.resourceId = responses[i].resourceId;
			ctx.secCtxId = responses[i].secCtxId;
			outputSecCtxChain = recoder.encode(ctx, outputSecCtxChain, null);
		}
		assertEquals(secCtxChain, outputSecCtxChain);
	}
	
	@Test
	public void testInvalidSecCtxChain() {
		V1ContextRecoder recoder = new V1ContextRecoder();
		String secCtxChain = ";prof1|secCtx1;prof2|secCtx2;prof3|secCtx3";
		DecodingResponse[] responses = resolveResponses(secCtxChain, recoder);
		assertEquals(4, responses.length);
		assertNull(responses[0].resourceId);
		assertNull(responses[0].secCtxId);
		for (int i=1; i<responses.length; i++) {
			assertEquals("secCtx"+i, responses[i].secCtxId);
			assertEquals("prof"+i, responses[i].resourceId);
		}
		
		secCtxChain = ";|;prof2|secCtx2;prof3|secCtx3";
		responses = resolveResponses(secCtxChain, recoder);
		assertEquals(4, responses.length);
		assertNull(responses[0].resourceId);
		assertNull(responses[0].secCtxId);
		assertNull(responses[1].resourceId);
		assertNull(responses[1].secCtxId);
		for (int i=2; i<responses.length; i++) {
			assertEquals("secCtx"+i, responses[i].secCtxId);
			assertEquals("prof"+i, responses[i].resourceId);
		}
		
		secCtxChain = ";prof1|;|secCtx2;prof3|secCtx3";
		responses = resolveResponses(secCtxChain, recoder);
		assertEquals(4, responses.length);
		assertNull(responses[0].resourceId);
		assertNull(responses[0].secCtxId);
		assertEquals("prof1",responses[1].resourceId);
		assertNull(responses[1].secCtxId);
		assertNull(responses[2].resourceId);
		assertEquals("secCtx2",responses[2].secCtxId);
		for (int i=3; i<responses.length; i++) {
			assertEquals("secCtx"+i, responses[i].secCtxId);
			assertEquals("prof"+i, responses[i].resourceId);
		}

		secCtxChain = "";
		responses = resolveResponses(secCtxChain, recoder);
		assertNotNull(responses);
		assertEquals(1, responses.length);
		assertNull(responses[0].chain);
		assertNull(responses[0].resourceId);
		assertNull(responses[0].secCtxId);
		
		secCtxChain = null;
		responses = resolveResponses(secCtxChain, recoder);
		assertNull(responses);
	}
	
	public static DecodingResponse[] resolveResponses(String contextIdChain, ICtxRecoder ctxRecoder) {
		if (contextIdChain==null)
			return null;
		List<DecodingResponse> responses = new ArrayList<DecodingResponse>();
		String currentChain = contextIdChain;
		while (currentChain!=null) {
			DecodingResponse resp  = ctxRecoder.decode(null, currentChain, null);
			if (resp!=null) {
				currentChain = resp.chain;
				responses.add(resp);
			} else
				return responses.toArray(new DecodingResponse[0]);
		}
		return responses.toArray(new DecodingResponse[0]);
	}
}
