/**
 * 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.data.index.ws.dataprov;

import java.text.CharacterIterator;
import java.text.StringCharacterIterator;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import pl.edu.icm.yadda.service.search.searching.stats.FieldStats;
import pl.edu.icm.yadda.service.search.searching.stats.QueryStats;
import pl.edu.icm.yadda.service.search.searching.stats.ValueStats;

/**
 * Query stats parser.
 * @author mhorst
 *
 */
public class QueryStatsParser {

	/**
	 * Parses QueryStats to XML representation.
	 * No data sorting is performed!
	 * @param queryStats
	 * @return QueryStats XML representation
	 */
	public static List<String> parseQueryStats(QueryStats queryStats) {
		if (queryStats==null)
			return null;
		if (queryStats.getFieldStats()==null ||
				queryStats.getFieldStats().size()==0)
			return new ArrayList<String>();
		List<String> results = new ArrayList<String>();
		Iterator<? extends FieldStats> it = queryStats.getFieldStats().iterator();
		while (it.hasNext())
			results.addAll(parseFieldStats(it.next()));
		return results;
	}
	
	/**
	 * Parses FieldStats to XML representation.
	 * @param fieldStats
	 * @return FieldStats XML representation
	 */
	private static List<String> parseFieldStats(FieldStats fieldStats) {
		List<String> result = new ArrayList<String>();
		if (fieldStats==null || fieldStats.getFieldName()==null
				|| fieldStats.getStats()==null)
			return result;
		Iterator<? extends ValueStats> it = fieldStats.getStats().iterator();
		while (it.hasNext())
			result.add(parseValueStats(fieldStats.getFieldName(), it.next()));
		return result;
	}

	
	/**
	 * Parses ValueStats to XML representation.
	 * @param fieldName
	 * @param valueStats
	 * @return ValueStats XML representation
	 */
	private static String parseValueStats(String fieldName, ValueStats valueStats) {
		StringBuffer strBuff = new StringBuffer();
		strBuff.append("<row>");
		strBuff.append("<groupresult field=\"");
		strBuff.append(fieldName);
		strBuff.append("\">");
		strBuff.append("<value>");
//		value needs to be escaped
		strBuff.append(escapeForXML(valueStats.getValue()));
		strBuff.append("</value>");
		strBuff.append("<count>");
		strBuff.append(valueStats.getOccurences());
		strBuff.append("</count>");
		strBuff.append("</groupresult>");
		strBuff.append("</row>");
		return strBuff.toString();		
	}
	
	/**
	  * Escape characters for text appearing as XML data, between tags.
	  * 
	  * <P>The following characters are replaced with corresponding character entities : 
	  * <table border='1' cellpadding='3' cellspacing='0'>
	  * <tr><th> Character </th><th> Encoding </th></tr>
	  * <tr><td> < </td><td> &lt; </td></tr>
	  * <tr><td> > </td><td> &gt; </td></tr>
	  * <tr><td> & </td><td> &amp; </td></tr>
	  * <tr><td> " </td><td> &quot;</td></tr>
	  * <tr><td> ' </td><td> &#039;</td></tr>
	  * </table>
	  * 
	  * <P>Note that JSTL's {@code <c:out>} escapes the exact same set of 
	  * characters as this method. <span class='highlight'>That is, {@code <c:out>}
	  *  is good for escaping to produce valid XML, but not for producing safe HTML.</span>
	  */
	  public static String escapeForXML(String aText) {
		if (aText == null)
			return null;
		final StringBuilder result = new StringBuilder();
		final StringCharacterIterator iterator = new StringCharacterIterator(
				aText);
		char character = iterator.current();
		while (character != CharacterIterator.DONE) {
			if (character == '<') {
				result.append("&lt;");
			} else if (character == '>') {
				result.append("&gt;");
			} else if (character == '\"') {
				result.append("&quot;");
			} else if (character == '\'') {
				result.append("&#039;");
			} else if (character == '&') {
				result.append("&amp;");
			} else {
				result.append(character);
			}
			character = iterator.next();
		}
		return result.toString();
	}
}
