/**
 * Copyright 2008-2009 DRIVER PROJECT (ICM UW)
 * Original author: Marek Horst
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package eu.dnetlib.resultset.impl.containers;

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

import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;

import eu.dnetlib.resultset.impl.CreatePullRSType;
import eu.dnetlib.resultset.impl.CreatePushRSType;
import eu.dnetlib.resultset.impl.PullResultSetObject;
import eu.dnetlib.resultset.impl.PushResultSetObject;
import eu.dnetlib.resultset.impl.ResultSetObject;
import eu.dnetlib.data.index.utils.SpringUtils;

import static org.junit.Assert.*;

/**
 * ResultSetObject hibernate container test class. 
 * This whole test class is deprecated as the ResultSetObjectHibernateContainer
 * was removed from spring configuration and is currently not supported.
 * @author mhorst
 *
 */
@Deprecated
public class ResultSetObjectHibernateContainerTest {

	ApplicationContext ctx = null;
	
	ResultSetObjectHibernateContainer container = null;
	
	@Before
	public void start() {
		ctx = SpringUtils.getSpringContext(SpringUtils.DEFAULT_JUNIT_RESOURCE);
		container = (ResultSetObjectHibernateContainer) ctx.getBean("RSObjectHibernateContainer");
	}
	
	@Test
	public void testMaintainPullRS() {
		String resultSetId = "dummyResultSetId"+System.currentTimeMillis();
		int expiryTime = 30000;
		String dataProviderServiceAddress = "DummydataProviderServiceAddress";
		String bdId = "dummyBdId";
		int initialPageSize = 10;
		int pullRsSize = 50;
		
//		CreatePullRSType values
		int typeTotal = 10;
		int typeKeepAliveTime = 5;
		String typeStyleSheet = "someStyleSheet";
		CreatePullRSType createPullRS_type = new CreatePullRSType();
		createPullRS_type.setTotal(typeTotal);
		createPullRS_type.setKeepAliveTime(typeKeepAliveTime);
		createPullRS_type.setStyleSheet(typeStyleSheet);
		try {
			PullResultSetObject pullRSObject = new PullResultSetObject(resultSetId,
					expiryTime, dataProviderServiceAddress, bdId, 
					initialPageSize, pullRsSize, null);
			pullRSObject.setCreatePullRS_type(createPullRS_type);
//			setting booleans
			for (int i=0; i<pullRSObject.getRetrievedPages().length; i++) {
				if (i%2==0) {
					pullRSObject.getRetrievedPages()[i] = true;
					pullRSObject.getData().set(i, new String[]{"val1-"+i,"val2-"+i});
				}
			}
			container.store(pullRSObject);
			PullResultSetObject retrievedPullRSObject = (PullResultSetObject) container.getWithStoredData(resultSetId);
			assertNotNull(retrievedPullRSObject);
			assertEquals(ResultSetObject.ResultSetType.PULL_RS, retrievedPullRSObject.getResultSetType());
			assertEquals(resultSetId, retrievedPullRSObject.getResultSetId());
			assertEquals(resultSetId, retrievedPullRSObject.getResultSetId());
			assertEquals(expiryTime, retrievedPullRSObject.getExpiryTime());
			assertEquals(pullRSObject.getExpirationTime() ,retrievedPullRSObject.getExpirationTime());
			assertEquals(dataProviderServiceAddress, retrievedPullRSObject.getDataProviderServiceAddress());
			assertEquals(bdId, retrievedPullRSObject.getBdId());
			assertEquals(initialPageSize, retrievedPullRSObject.getInitialPageSize());
			assertEquals(pullRsSize, retrievedPullRSObject.getPullRsSize());
			
			
//			checking CreatePullRSType
			assertNotNull(retrievedPullRSObject.getCreatePullRS_type());
			assertEquals((int)typeTotal, (int)retrievedPullRSObject.getCreatePullRS_type().getTotal());
			assertEquals((int)typeKeepAliveTime, (int)retrievedPullRSObject.getCreatePullRS_type().getKeepAliveTime());
			assertEquals(typeStyleSheet, retrievedPullRSObject.getCreatePullRS_type().getStyleSheet());
			
//			checking data
			for (int i=0; i<pullRSObject.getRetrievedPages().length; i++) {
				if (i%2==0) {
					assertTrue(retrievedPullRSObject.getRetrievedPages()[i]);
					assertNotNull(retrievedPullRSObject.getData().get(i));
					assertEquals(pullRSObject.getData().get(i).length, retrievedPullRSObject.getData().get(i).length);
					assertEquals(pullRSObject.getData().get(i)[0], retrievedPullRSObject.getData().get(i)[0]);
					assertEquals(pullRSObject.getData().get(i)[1], retrievedPullRSObject.getData().get(i)[1]);
				} else {
					assertFalse(retrievedPullRSObject.getRetrievedPages()[i]);
					assertEquals(0, retrievedPullRSObject.getData().get(i).length);
//					assertNull(retrievedPullRSObject.getData().get(i));
				}
			}
			
		} finally {
			container.remove(resultSetId);
			assertNull(container.get(resultSetId));
		}
	}

	@Test
	public void testMaintainPushRS() {
		String resultSetId = "dummyResultSetId"+System.currentTimeMillis();
		int expiryTime = 30000;
		int dataSize = 100;
		
//		CreatePushRSType values
		int typeKeepAliveTime = 5;
		CreatePushRSType createPushRSType = new CreatePushRSType();
		createPushRSType.setKeepAliveTime(typeKeepAliveTime);
		
		try {
			PushResultSetObject pushRSObject = new PushResultSetObject(
					resultSetId, expiryTime, createPushRSType);
//			storing data
			pushRSObject.setData(new String[dataSize]);
			for (int i=0; i<pushRSObject.getData().length; i++) {
				if (i%2==0) {
					pushRSObject.getData()[i] = "pushRSdata"+i;
				}
			}
			container.store(pushRSObject);
			PushResultSetObject retrievedPushRSObject = (PushResultSetObject) container.get(resultSetId);
			assertNotNull(retrievedPushRSObject);
			assertEquals(resultSetId,retrievedPushRSObject.getResultSetId());
			assertEquals(expiryTime,retrievedPushRSObject.getExpiryTime());
			assertEquals(pushRSObject.getExpirationTime() ,retrievedPushRSObject.getExpirationTime());
			assertNotNull(retrievedPushRSObject.getCreatePushRS_type());
			assertEquals((int)typeKeepAliveTime,
					(int)retrievedPushRSObject.getCreatePushRS_type().getKeepAliveTime());
//			checking data
			assertEquals(pushRSObject.getData().length, retrievedPushRSObject.getData().length);
			for (int i=0; i<pushRSObject.getData().length; i++) {
				if (i%2==0)
					assertEquals(pushRSObject.getData()[i], retrievedPushRSObject.getData()[i]);
				else
					assertNull(retrievedPushRSObject.getData()[i]);
			}
			
		} finally {
			container.remove(resultSetId);
			assertNull(container.get(resultSetId));
		}
	}

	@Test
	public void testRemoveForNonExistingRSId() {
		String rsId = "nonExistingRSId";
		assertNull(container.remove(rsId));
	}
	
	@Test
	public void testCleanup() throws InterruptedException {
		Random rand = new Random();
		int objectsCount = 10;
		String resultSetId = null;
		List<String> rsIds = new ArrayList<String>(objectsCount);
//		expiry time in seconds
		int expiryTime = 5;
		
//		storing all objects
		for (int i=0; i<objectsCount; i++) {
			resultSetId = "rsId" + System.currentTimeMillis() + '-' + rand.nextInt(100);
			container.store(new PushResultSetObject(
					resultSetId, expiryTime, null));
			rsIds.add(resultSetId);
		}

		assertEquals(objectsCount, rsIds.size());
		for (int i=0; i<objectsCount; i++) {
			assertNotNull(container.get(rsIds.get(i)));
		}
		assertEquals(0, container.cleanup());
		
//		waiting for expiration time
		Thread.sleep(expiryTime*1000);
		
		assertEquals(objectsCount, container.cleanup());
		
		for (int i=0; i<objectsCount; i++) {
			assertNull(container.get(rsIds.get(i)));
		}
	}
}
