/**
 * Copyright © 2008-2009 DRIVER PROJECT (ICM UW)
 *
 * 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;

import java.security.InvalidParameterException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.log4j.Logger;

/**
 * PullResultSet object utility class.
 * @author Marek Horst
 * @version 0.01
 *
 */
public class PullResultSetObjectUtils {

	protected static final Logger log = Logger.getLogger(PullResultSetObjectUtils.class);
	
	/**
	 * Returns data from page number given as parameter.
	 * @param pageNumber
	 * @param fromPosition
	 * @param toPosition
	 * @param data
	 * @return String[] data
	 */
	public static String[] getPageData(final int pageNumber, 
			final int fromPosition, final int toPosition, 
			final List<String[]> data) {
		
		if (data==null)
			throw new InvalidParameterException("data cannot be null");
		if (pageNumber<1 || pageNumber>data.size())
			throw new InvalidParameterException("pageNumber must be within range " +
					"<"+1+";"+data.size()+">");
		String[] tempData = data.get(pageNumber-1);
		if (tempData==null) {
			log.debug("null data package, pageNumber: "+pageNumber);
			return new String[toPosition-fromPosition+1];
		}
		if (fromPosition==1 && toPosition>=tempData.length) {
			return tempData;
		} else {
			int startElement = fromPosition-1;
			String[] resultData = new String[toPosition-fromPosition+1];
			for(int i=0; i<resultData.length; i++) {
				resultData[i] = tempData[startElement+i];
			}
			return resultData;
		}
	}
	
	/**
	 * Returns pull result set data for given range.
	 * @param fromPosition
	 * @param toPosition
	 * @param initialPageSize
	 * @param pullRsSize
	 * @param data
	 * @return array of data
	 */
	public static String[] getData(final int fromPosition, final int toPosition, 
			final int initialPageSize, final int pullRsSize, final List<String[]> data) {
		if (fromPosition>pullRsSize)
			return new String[0];
		int toPositionLocal = toPosition;
		if (toPositionLocal>pullRsSize)
			toPositionLocal=pullRsSize;
		List<String> resultList = new ArrayList<String>();
		
		int startPageNumber = (fromPosition-1)/initialPageSize + 1;
		log.debug("start page number: "+startPageNumber);
		int lastAvailaibleElementNumber = initialPageSize*startPageNumber;
		int currentPageNumber = startPageNumber;
		boolean stopWorking = false;
		while (!stopWorking) {
			log.debug("working on curentPageNumber: "+currentPageNumber);
			lastAvailaibleElementNumber = initialPageSize*currentPageNumber;
			int pckgStartElement;
			if (currentPageNumber==startPageNumber) {
				pckgStartElement = fromPosition%initialPageSize;
				if (pckgStartElement==0)
					pckgStartElement = initialPageSize;
			} else
				pckgStartElement = 1;

			log.debug("pckgStartElement: "+pckgStartElement);
			if (lastAvailaibleElementNumber>=toPositionLocal) {
				stopWorking = true;
			} 
			int pckgEndElement;
			if (stopWorking) {
//				if the last page of results
				pckgEndElement = toPositionLocal-(initialPageSize*
						(currentPageNumber-1));
			} else
				pckgEndElement = initialPageSize;
			log.debug("pckgEndElement: "+pckgEndElement);
			String[] currentPackage = getPageData(currentPageNumber, 
					pckgStartElement, pckgEndElement, data);
			if (currentPackage!=null && currentPackage.length>0)
				resultList.addAll(Arrays.asList(currentPackage));
			
			currentPageNumber = currentPageNumber+1;
		}
		return resultList.toArray(new String[0]);
	}
}
