/**
 * 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.common.profile.utils;

import java.util.Iterator;
import java.util.List;

import eu.dnetlib.common.profile.IndexBody;
import eu.dnetlib.common.profile.IndexConfiguration;
import eu.dnetlib.common.profile.IndexStatus;
import eu.dnetlib.common.profile.Profile;
import eu.dnetlib.common.profile.ProfileHeader;
import eu.dnetlib.common.profile.Protocol;
import eu.dnetlib.common.profile.blackboard.Blackboard;
import eu.dnetlib.common.profile.blackboard.Message;
import eu.dnetlib.common.profile.blackboard.Parameter;



/**
 * Class used for converting object data  into profile string representation.
 * @author mhorst
 *
 */
public class ProfileMarshaller {
	
	/**
	 * Generates xml representation of ProfileHeader object.
	 * @param profileHeader
	 * @return xml representation of ProfileHeader object
	 */
	public static String generateProfileHeader(ProfileHeader profileHeader) {
		if (profileHeader == null)
			return null;
		StringBuffer strBuff = new StringBuffer("<HEADER>");
		strBuff.append("<RESOURCE_IDENTIFIER value=\""
				+ profileHeader.getResourceIdentifier() + "\"/>");
		strBuff.append("<RESOURCE_TYPE value=\""
				+ profileHeader.getResourceType() + "\"/>");
		strBuff.append("<RESOURCE_KIND value=\""
				+ profileHeader.getResourceKind() + "\"/>");
		if (profileHeader.getResourceURI() != null)
			strBuff.append("<RESOURCE_URI value=\""
					+ profileHeader.getResourceURI() + "\"/>");
		else
			strBuff.append("<RESOURCE_URI value=\"\"/>");
		
		if (profileHeader.getDateOfCreation() != null)
			strBuff.append("<DATE_OF_CREATION value=\""
					+ profileHeader.getDateOfCreation() + "\"/>");
		else
			strBuff.append("<DATE_OF_CREATION value=\"\"/>");

		if (profileHeader.getParentId() != null)
			strBuff.append("<PARENT_ID value=\"" + profileHeader.getParentId()
					+ "\" type=\"" +  profileHeader.getParentType()
					+ "\"/>");
		
		if (profileHeader.getProtocols()!=null && profileHeader.getProtocols().size()>0) {
			strBuff.append("<PROTOCOLS>");
			Iterator<Protocol> itProtocol = profileHeader.getProtocols().iterator();
			while (itProtocol.hasNext()) {
				Protocol currentProtocol = itProtocol.next();
				strBuff.append("<PROTOCOL address=\"");
				strBuff.append(currentProtocol.getAddress());
				strBuff.append("\" name=\"");
				strBuff.append(currentProtocol.getName());
				strBuff.append("\"/>");
			}
			strBuff.append("</PROTOCOLS>");
		}
		
		strBuff.append("</HEADER>");
		return strBuff.toString();
	}
	
	/**
	 * Generates Message part of Blackboard.
	 * Returns xml representation of Message object.
	 * @param messages
	 * @return xml representation of Message object
	 */
	public static String generateMessagePartOfBlackBoard(List<Message> messages) {
		if (messages==null)
			return null;
		StringBuffer strBuff = new StringBuffer();
		Iterator<Message> it = messages.iterator();
		while (it.hasNext()) {
			Message message = it.next();
			strBuff.append("<MESSAGE date=\"");
			strBuff.append(message.getDate());
			strBuff.append("\" id=\"");
			strBuff.append(message.getId());
			strBuff.append("\">");
			strBuff.append("<ACTION>");
			strBuff.append(message.getAction());
			strBuff.append("</ACTION>");
			if (message.getParamList()!=null) {
				Iterator<Parameter> itParam = message.getParamList().iterator();
				while (itParam.hasNext()) {
					Parameter currentParam = itParam.next();
					strBuff.append("<PARAMETER value=\"");
					strBuff.append(currentParam.getValue());
					strBuff.append("\" name=\"");
					strBuff.append(currentParam.getName());
					strBuff.append("\"/>");
				}
			}
			strBuff.append("<ACTION_STATUS>");
			strBuff.append(message.getActionStatus());
			strBuff.append("</ACTION_STATUS>");
			strBuff.append("</MESSAGE>");
		}
		return strBuff.toString();
	}
	
	/**
	 * Generates Message part of Blackboard.
	 * Returns xml representation of Message object.
	 * @param message
	 * @return xml representation of Message object
	 */
	public static String generateMessagePartOfBlackBoard(Message message) {
		if (message==null)
			return null;
		StringBuffer strBuff = new StringBuffer();
		strBuff.append("<MESSAGE date=\"");
		strBuff.append(message.getDate());
		strBuff.append("\" id=\"");
		strBuff.append(message.getId());
		strBuff.append("\">");
		strBuff.append("<ACTION>");
		strBuff.append(message.getAction());
		strBuff.append("</ACTION>");
		if (message.getParamList()!=null) {
			Iterator<Parameter> itParam = message.getParamList().iterator();
			while (itParam.hasNext()) {
				Parameter currentParam = itParam.next();
				strBuff.append("<PARAMETER value=\"");
				strBuff.append(currentParam.getValue());
				strBuff.append("\" name=\"");
				strBuff.append(currentParam.getName());
				strBuff.append("\"/>");
			}
		}
		strBuff.append("<ACTION_STATUS>");
		strBuff.append(message.getActionStatus());
		strBuff.append("</ACTION_STATUS>");
		strBuff.append("</MESSAGE>");
		return strBuff.toString();
	}
	
	/**
	 * Generates xml representation of blackboard object.
	 * @param blackboard
	 * @return xml representation of blackboard object
	 */
	public static String generateBlackboardPartOfProfile(Blackboard blackboard) {
		if (blackboard==null)
			return null;
		StringBuffer strBuff = new StringBuffer("<BLACKBOARD>");
		if (blackboard.getLastRequest()!=null) {
			strBuff.append("<LAST_REQUEST date=\"");
			strBuff.append(blackboard.getLastRequest().getDate());
			strBuff.append("\">");
			strBuff.append(blackboard.getLastRequest().getValue());
			strBuff.append("</LAST_REQUEST>");
		}
		if (blackboard.getLastResponse()!=null) {
			strBuff.append("<LAST_RESPONSE date=\"");
			strBuff.append(blackboard.getLastResponse().getDate());
			strBuff.append("\">");
			strBuff.append(blackboard.getLastResponse().getValue());
			strBuff.append("</LAST_RESPONSE>");
		}
		String messagePartString = generateMessagePartOfBlackBoard(blackboard.getMessages());
		if (messagePartString!=null) {
			strBuff.append(messagePartString);
		}
		strBuff.append("</BLACKBOARD>");
		return strBuff.toString();
	}
	
	/**
	 * Generates simple profile with blackboard body part.
	 * Returns xml profile representation.
	 * @param profileHeader
	 * @param blackboard
	 * @return xml profile representation
	 */
	public static String generateBBProfile(ProfileHeader profileHeader, Blackboard blackboard) {
		return generateBBProfile(profileHeader, blackboard, null);
	}
	
	/**
	 * Generates simple profile with blackboard body part and additional body part passed as String param.
	 * Returns xml profile representation.
	 * @param profileHeader
	 * @param blackboard
	 * @param additionalBodyPart
	 * @return xml profile representation
	 */
	public static String generateBBProfile(ProfileHeader profileHeader, Blackboard blackboard,
			String additionalBodyPart) {
		StringBuffer strBuff = new StringBuffer("<RESOURCE_PROFILE>");
		String profileHeaderPartStr = generateProfileHeader(profileHeader);
		if (profileHeaderPartStr!=null)
			strBuff.append(profileHeaderPartStr);
		strBuff.append("<BODY>");
		String blackboardPartStr = generateBlackboardPartOfProfile(blackboard);
		if (blackboardPartStr!=null)
			strBuff.append(blackboardPartStr);
		if (additionalBodyPart!=null)
			strBuff.append(additionalBodyPart);
		strBuff.append("</BODY>");
		strBuff.append("</RESOURCE_PROFILE>");
		return strBuff.toString();
	}
	
	/**
	 * Generates index profile string representation for given profile
	 * @param indexProfile
	 * @return index profile string representation
	 */
	public static String generateIndexProfile(Profile indexProfile) {
		if (indexProfile == null)
			return null;
		return generateIndexProfile(indexProfile.getHeader(), (IndexBody) indexProfile.getBody());
	}
	
	/**
	 * Generates simple profile with index body part.
	 * Returns xml profile representation.
	 * @param profileHeader
	 * @param indexBody
	 * @return xml profile representation
	 */
	public static String generateIndexProfile(ProfileHeader profileHeader, IndexBody indexBody) {
		StringBuffer strBuff = new StringBuffer("<RESOURCE_PROFILE>");
		String profileHeaderPartStr = generateProfileHeader(profileHeader);
		if (profileHeaderPartStr!=null)
			strBuff.append(profileHeaderPartStr);
		if (indexBody!=null) {
			strBuff.append("<BODY>");
			String indexConfPartStr = generateIndexConfPartOfProfile(
					indexBody.getConfiguration());
			if (indexConfPartStr!=null)
				strBuff.append(indexConfPartStr);
			String indexStatusPartStr = generateIndexStatusPartOfProfile(
					indexBody.getStatus());
			if (indexStatusPartStr!=null)
				strBuff.append(indexStatusPartStr);
			strBuff.append("<SECURITY_PARAMETERS/>");
			strBuff.append("</BODY>");
		}
		strBuff.append("</RESOURCE_PROFILE>");
		return strBuff.toString();
	}
	
	public static String generateIndexConfPartOfProfile(IndexConfiguration indexConf) {
		if (indexConf==null)
			return null;
		StringBuffer strBuff = new StringBuffer();
		strBuff.append("<CONFIGURATION>");

		strBuff.append("<METADATA_FORMAT>");
		strBuff.append(indexConf.getMetaDataFormat());
		strBuff.append("</METADATA_FORMAT>");
		
		strBuff.append("<METADATA_FORMAT_INTERPRETATION>");
		strBuff.append(indexConf.getMetaDataFormatInterpretation());
		strBuff.append("</METADATA_FORMAT_INTERPRETATION>");
		
		strBuff.append("<METADATA_FORMAT_LAYOUT>");
		strBuff.append(indexConf.getMetaDataFormatLayout());
		strBuff.append("</METADATA_FORMAT_LAYOUT>");
		
		strBuff.append("<INDEX_SIZE>");
		strBuff.append(indexConf.getSize());
		strBuff.append("</INDEX_SIZE>");
		
		strBuff.append("<INDEX_STALE>");
		strBuff.append(indexConf.isInvalid());
		strBuff.append("</INDEX_STALE>");
		
		strBuff.append("</CONFIGURATION>");
		return strBuff.toString();
		
	}
	
	public static String generateIndexStatusPartOfProfile(IndexStatus indexStatus) {
		if (indexStatus==null)
			return null;
		StringBuffer strBuff = new StringBuffer();
		strBuff.append("<STATUS>");
		
		if (indexStatus.getLastUpdate()!=null) {
			strBuff.append("<INDEX_LAST_UPDATE>");
			strBuff.append(indexStatus.getLastUpdate());
			strBuff.append("</INDEX_LAST_UPDATE>");
		}
		
		strBuff.append("</STATUS>");
		return strBuff.toString();
	}
}
