package com.tandbergtv.watchpoint.pmm.web.util;

import java.util.Collection;
import java.util.List;

import com.tandbergtv.watchpoint.pmm.entities.Title;
import com.tandbergtv.watchpoint.pmm.title.conf.Specification;
import com.tandbergtv.watchpoint.pmm.title.conf.TitleConf;
import com.tandbergtv.watchpoint.pmm.web.formbeans.title.TitleData;
import com.tandbergtv.watchpoint.pmm.web.formbeans.title.Variable;
import com.tandbergtv.workflow.core.Datatype;

/**
 * Helper class for UI Title section.
 *  
 * @author Raj Prakash
 */
public class TitleHelper {
	
	public static final String ASSET_LOCATION_NAME = "_assetLocation";
	//TODO get from resource bundle
	private static final String ASSET_LOCATION_DISPLAYNAME = "Asset Location";
	
	/**
	 * Copies information from title (DB) to titleData (UI) objects
	 */
	@Deprecated
	public static void copyAllTitleToTitleData(Title rootTitle, Collection<TitleData> titlesData) {
		/*for(TitleData td : titlesData) {
			Title t = rootTitle.getTitle(td.getName());
			
			if (t != null)
				copyTitleToTitleData(t, td);
		}*/
	}
	
	/**
	 * Copies metadata from titleData (UI) to title (DB) objects
	 */
	@Deprecated
	public static void copyMetadata(List<TitleData> titlesData, Title rootTitle) {
		/*for(TitleData td : titlesData) {
			Title t = rootTitle.getTitle(td.getName());
			
			if (t != null) {
				copyMetadata(td, t);
			}
			 FIXME Else what? Create the descendant? 
		}*/
	}
	
	/**
	 * Gets titleData (UI) objects for the given specification.
	 */
	public static CustomArrayList<TitleData> getTitlesDataForSpec(String specName) {
		CustomArrayList<TitleData> titlesData = new CustomArrayList<TitleData>(TitleData.class);
		Specification spec = TitleFacade.getSpecificationByName(specName);
		if(spec != null) {
			Collection<TitleConf> titleConfs = spec.getAllTitleConf();
			if(titleConfs != null) {
				copyAllTitleConfToTitleData(titleConfs, titlesData);
			}
		}
		return titlesData;
	}
	
	/**
	 * Copies information from title to titleData. 
	 */
	@SuppressWarnings("unused")
    @Deprecated
	private static void copyTitleToTitleData(Title title, TitleData td) {
		/*//copying assetLocation field
		Variable v = td.getVariableByName(ASSET_LOCATION_NAME);
		if(v != null)
			v.setValue(title.getAssetLocation());
		
		//copying title metadata as variables in titleData
		if(title.getMetadata() != null) {
			for(TitleMetadata metadata : title.getMetadata()) {
				v = td.getVariableByName(metadata.getName());
				
				if (v != null)
					v.setValue(metadata.getValue());
			}
		}*/
	}
	
	/**
	 * Checks if the file path has been modified to a non-null value.
	 */
	public static boolean newFileMapped(String oldFilePath, String newFilePath) {
		if(!containsValue(newFilePath))
			return false;
		
		if(!containsValue(oldFilePath))
			return true;
		
		return !oldFilePath.equals(newFilePath);
	}
	
	/**
	 * Copies metadata from titleData to title.
	 */
	@SuppressWarnings("unused")
    @Deprecated
	private static void copyMetadata(TitleData td, Title correspondingTitle) {
		/*//copying titleData variables to title metadata
		if(td.getVariables() != null) {
			for(com.tandbergtv.watchpoint.pmm.web.formbeans.title.Variable tdVar : td.getVariables()) {
				
				 As we are copying only the metadata,
				 *  ignore the titleData variable that refer to assetLocation
				 
				if(tdVar.getName().equals(ASSET_LOCATION_NAME))
					continue;
				
				//if titleData variable has value
				if(containsValue(tdVar.getValue())) {
					TitleMetadata metadata = correspondingTitle.getMetadataField(tdVar.getName());
					//if there is a corresponding metadata field in title, update the value in metadata
					if(metadata != null) {
						metadata.setValue(tdVar.getValue());
					}
					//if corresponding metadata field does not exist in title, create the metadata field.
					else {
						metadata = new TitleMetadata(tdVar.getName(), tdVar.getValue());
						correspondingTitle.addMetadata(metadata);
					}
				}
				//if titleData variable does not have value
				else {
					TitleMetadata metadata = correspondingTitle.getMetadataField(tdVar.getName());
					//if corresponding metadata field exist in the title, remove the metadata field.
					 if(metadata != null) {
						correspondingTitle.removeMetadataField(tdVar.getName());
					}
				}
			}
		}*/
	}

	/**
	 * Copies information from titleConf (spec) to titleData (UI) objects
	 */
	private static void copyAllTitleConfToTitleData(Collection<TitleConf> titleConfs, List<TitleData> titlesData) {
		int i = 0;
		for(TitleConf tc : titleConfs) {
			convertTitleConfToTitleData(tc, titlesData.get(i++));
		}
	}
	
	/**
	 * Copies information from titleConf to titleData.
	 */
	private static TitleData convertTitleConfToTitleData(TitleConf tc, TitleData td) {
		td.setName(tc.getName());
		int i = 0;
		if(tc.isHasAsset()) {
			fillAssetLocationVariableInfo(td.getVariables().get(i++));
		}
		Collection<com.tandbergtv.watchpoint.pmm.title.conf.Variable> tcVariables = tc.getMetadata();
		if(tcVariables != null) {
			for(com.tandbergtv.watchpoint.pmm.title.conf.Variable tcVariable : tcVariables) {
				convertSpecVariableToVariable(tcVariable, td.getVariables().get(i++));
			}
		}
		return td;
	}
	
	/**
	 * Copies information from specification variable to titleConf variable.
	 */
	private static void convertSpecVariableToVariable(com.tandbergtv.watchpoint.pmm.title.conf.Variable specVariable, Variable v) {
		v.setName(specVariable.getName());
		v.setDisplayName(specVariable.getDisplayName());
		v.setDataType("STRING");
		v.setRequired(false);
		v.setFilePath(false);
	}

	/**
	 * Makes the given variable as asset location variable.
	 */
	private static void fillAssetLocationVariableInfo(Variable v) {
		v.setName(ASSET_LOCATION_NAME);
		v.setDisplayName(ASSET_LOCATION_DISPLAYNAME);
		v.setDataType(Datatype.FILE.name());
		v.setFilePath(true);
	}
	
	/**
	 * Checks if the given string is not null and not (empty or blank) string
	 */
	public static boolean containsValue(String s) {
		return s != null && s.trim().length() > 0;
	}
	
	/*
	 * Safely (handles null argument) trims the given string.
	 * If the string is empty or blank, returns null.
	 */
	public static String trim(String s) {
		if(s == null)
			return null;
		
		s = s.trim();
		
		if(s.length() == 0)
			s = null;
		
		return s;
	}

	/**
	 * Returns (s1 == null) ? (s2 == null) : s1.equals(s2)
	 */
	public static boolean equals(String s1, String s2) {
		return (s1 == null) ? (s2 == null) : s1.equals(s2);
	}

}
