/**
 * GetOriginalFileInfoMessageHandler.java
 * Created on Apr 10, 2009
 * (C) Copyright TANDBERG Television Ltd.
 */
package com.tandbergtv.watchpoint.contentmgmt.communication.handlers;

import java.util.List;

import com.tandbergtv.cms.portal.util.transaction.Transactional;
import com.tandbergtv.metadatamanager.model.Asset;
import com.tandbergtv.metadatamanager.model.Field;
import com.tandbergtv.watchpoint.communication.Util;
import com.tandbergtv.watchpoint.pmm.communication.HandlerErrorCode;
import com.tandbergtv.watchpoint.pmm.communication.MessageHandler;
import com.tandbergtv.watchpoint.pmm.communication.MessageHandlerException;
import com.tandbergtv.watchpoint.pmm.entities.Title;
import com.tandbergtv.watchpoint.pmm.title.ITitlePersistenceService;
import com.tandbergtv.workflow.core.service.ServiceRegistry;
import com.tandbergtv.workflow.message.IMessageKey;
import com.tandbergtv.workflow.message.IMessageUID;
import com.tandbergtv.workflow.message.WorkflowMessage;
import com.tandbergtv.workflow.message.WorkflowMessage.MessageType;

/**
 * @author Vlada Jakobac
 * 
 */
public class GetOriginalFileInfoMessageHandler implements MessageHandler {

	private static final String MATERIAL_ID = "materialId";
	private static final String ENCODE_PROFILE = "encodeProfile";
	private static final String ENCODE_FORMAT = "encodeFormat";
	private static final String HEIGHT = "height";
	private static final String WIDTH = "width";
	private static final String ASPECTRATIO = "aspectratio";
	private static final String BITRATE = "bitrate";
	private static final String LOOKUP_KEY = "lookupKey";
	private static final String DURATION = "duration";
	private static final String RESOLUTION = "resolution";
	private static final String MIME_TYPE = "mimeType";
	private static final String FILE_SIZE = "fileSize";
	private static final String FILE_NAME = "fileName";
	private static final String FILE_URI = "fileUri";
	private static final String TITLE_ID = "titleId";
	private static final String ASSET_ID = "assetId";

	private static final String LOOKUP_KEY_XPATH = "/tns:Fields/tns:CustomFields/tns:CustomField[@name=LookupKey]/@value";
	private static final String MATERIAL_ID_XPATH = "/tns:Fields/tns:CustomFields/tns:CustomField[@name=MaterialId]/@value";
	private static final String ENCODE_PROFILE_XPATH = "/tns:Fields/tns:CustomFields/tns:CustomField[@name=EncodeProfile]/@value";
	private static final String ENCODE_FORMAT_XPATH = "/tns:Fields/tns:CustomFields/tns:CustomField[@name=EncodeFormat]/@value";
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.tandbergtv.watchpoint.pmm.communication.MessageHandler#handleMessage
	 * (com.tandbergtv.workflow.message.WorkflowMessage)
	 */
	@Override
	@Transactional
	public WorkflowMessage handleMessage(WorkflowMessage message)
			throws Exception {

		Util.validateRequired(message, TITLE_ID, ASSET_ID);

		/* Get the title Id */
		Long titleId = Util.getLongValue(message, TITLE_ID);

		/* Get the Service Registry to allow fetching of the title */
		ServiceRegistry registry = ServiceRegistry.getDefault();
		ITitlePersistenceService service = registry
				.lookup(ITitlePersistenceService.class);

		/* Get the Title using the Service */
		Title title = null;
		try {
			title = service.get(titleId);
		} catch (Exception e) {
			String msg = "Failed to read the Title from the persistence service, error: "
					+ e.getMessage();
			throw new MessageHandlerException(
					HandlerErrorCode.OBJECT_NOT_PRESENT, msg, e);
		}

		if (title == null) {
			String msg = "Did not get a Title from the persistence service.";
			throw new MessageHandlerException(
					HandlerErrorCode.OBJECT_NOT_PRESENT, msg);
		}

		/* Get the asset Id */
		Long assetId = Util.getLongValue(message, ASSET_ID);

		/* Get the matching asset from the title */
		Asset groupAsset = title.getAsset();
		if (groupAsset == null) {
			String msg = "Did not get a group object for a given title.";
			throw new MessageHandlerException(
					HandlerErrorCode.OBJECT_NOT_PRESENT, msg);
		}
		/* Find the asset with the given assetId */
		Asset targetAsset = null;
		if (groupAsset.getId() == assetId)
			targetAsset = groupAsset;
		else {
			for (Asset asset : groupAsset.getAllDescendantItems(false)) {
				if (asset.getId() == assetId) {
					targetAsset = asset;
					break;
				}			
			}
		}
		
		if (targetAsset == null) {
			String msg = "Did not get an item object for a given assetId.";
			throw new MessageHandlerException(
					HandlerErrorCode.OBJECT_NOT_PRESENT, msg);
		}
		// find the original file with the given assetId
		com.tandbergtv.metadatamanager.model.File originalFile = null;
		List<com.tandbergtv.metadatamanager.model.File> files = targetAsset
				.getChildrenOfType(com.tandbergtv.metadatamanager.model.File.class);
		if (files != null) {
			for (com.tandbergtv.metadatamanager.model.File file : files) {
				if (file.isOriginal()) {
					originalFile = file;
					break;
				}
			}
		}
		if (originalFile == null) {
			String msg = "Could not find an original file associated with the given assetId.";
			throw new MessageHandlerException(
					HandlerErrorCode.OBJECT_NOT_PRESENT, msg);
		}

		/* Build the response Workflow Message */
		IMessageUID uid = message.getMessageUID();
		IMessageKey key = message.getKey();
		WorkflowMessage response = new WorkflowMessage(uid, key,
				MessageType.ack);
		String fileUri = (originalFile.getURL() != null) ? originalFile
				.getURL() : "";
		String fileName = (originalFile.getName() != null) ? originalFile
				.getName() : "";
		String fileSize = originalFile.getSize();
		String mimeType = (originalFile.getMIMEType() != null) ? originalFile
				.getMIMEType() : "";
		String resolution = (originalFile.getResolution() != null)
				? originalFile.getResolution()
				: "";
		String duration = (originalFile.getDuration() != null) ? originalFile
				.getDuration() : "";
		String bitrate = (originalFile.getBitrate() != null) ? originalFile.getBitrate() : "";		
		String aspectratio = (originalFile.getAspectratio() != null) ? originalFile.getAspectratio() : "";
		String width = originalFile.getWidth() + "";
		String height = originalFile.getHeight() + "";
		String encodeFormat = (String) getFieldValue (originalFile, ENCODE_FORMAT_XPATH);
		String encodeProfile = (String) getFieldValue (originalFile, ENCODE_PROFILE_XPATH);
		String materialId = (String) getFieldValue (originalFile, MATERIAL_ID_XPATH);
		String lookupKey = (String) getFieldValue (originalFile, LOOKUP_KEY_XPATH);
		
		response.putValue(FILE_URI, fileUri);
		response.putValue(FILE_NAME, fileName);
		response.putValue(FILE_SIZE, fileSize);
		response.putValue(MIME_TYPE, mimeType);
		response.putValue(RESOLUTION, resolution);
		response.putValue(DURATION, duration);
		response.putValue(BITRATE, bitrate);
		response.putValue(ASPECTRATIO, aspectratio);
		response.putValue(WIDTH, width);
		response.putValue(HEIGHT, height);
		response.putValue(ENCODE_FORMAT, encodeFormat);
		response.putValue(ENCODE_PROFILE, encodeProfile);
		response.putValue(MATERIAL_ID, materialId);
		response.putValue(LOOKUP_KEY, lookupKey);

		return response;

	}
	private Object getFieldValue(com.tandbergtv.metadatamanager.model.File file, String path) {
		Field field = file.getFirstField(path);
		
		if (field != null)
			return field.getTypedValue();
		
		return null;
	}
}
