package com.tandbergtv.watchpoint.pmm.web.actions.title;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.apache.struts.actions.DispatchAction;

import com.tandbergtv.watchpoint.pmm.entities.Title;
import com.tandbergtv.watchpoint.pmm.title.ITitleService;
import com.tandbergtv.watchpoint.pmm.title.provider.ITitleProvider;
import com.tandbergtv.watchpoint.pmm.title.provider.ITitleProviderRegistry;
import com.tandbergtv.watchpoint.pmm.web.formbeans.title.TitleData;
import com.tandbergtv.watchpoint.pmm.web.formbeans.title.TitleForm;
import com.tandbergtv.watchpoint.pmm.web.formbeans.title.Variable;
import com.tandbergtv.watchpoint.pmm.web.title.TitleExternalKeySerializer;
import com.tandbergtv.watchpoint.pmm.web.util.TitleFacade;
import com.tandbergtv.watchpoint.pmm.web.util.TitleHelper;
import com.tandbergtv.workflow.core.service.ServiceRegistry;
import com.tandbergtv.workflow.sanmanager.SANManagementException;

public abstract class TitleAction extends DispatchAction {
	
	private static final Logger logger = Logger.getLogger(TitleAction.class);
	
	/*
	 * Populate the Title Form with the Title information using the search data present in the form.
	 * The external flag determines if the title is from an external source or from the PMM
	 * persistence layer.
	 */ 
	protected void populateForm(TitleForm form, boolean external) {
		//find the title
		Title rootTitle = (external) ? getExternalTitle(form) : getInternalTitle(form);
		
		//populate form
		populateForm(form, rootTitle);
	}
	
	/*
	 * Populate the Title Form with the Title.
	 */
	@Deprecated
	protected void populateForm(TitleForm form, Title rootTitle) {
		/*
		// Store the title in the form
		form.setTitle(rootTitle);

		//set the type in the form as the root title's type
		String type = rootTitle.getSpecification();
		form.setType(type);

		String externalSourceId = rootTitle.getExternalLocation();
		String externalSourceName = "";
		if (externalSourceId != null && externalSourceId.trim().length() > 0) {
			ServiceRegistry serviceRegistry = ServiceRegistry.getDefault();
			ITitleProviderRegistry registry = serviceRegistry.lookup(ITitleProviderRegistry.class);
			ITitleProvider provider = registry.getProviderForTitle(externalSourceId);
			form.setExternalRefURL(provider.getTitleDisplayURL(rootTitle));
			externalSourceName = provider.getProviderInstance(externalSourceId).getName();
		}
		form.setAssetDB(externalSourceId);
		form.setAssetDBName(externalSourceName);

		//set status
		form.setStatus(rootTitle.getStatus().name());
		
		//set metadataLocation
		form.setMetadataLocation(rootTitle.getMetadataLocation());
		
		form.setTitlesData(TitleHelper.getTitlesDataForSpec(type));
		
		//copy title information from the found title to title data in the form
		TitleHelper.copyAllTitleToTitleData(rootTitle, form.getTitlesData());
		*/
	}

	/* Get the Title from the database using the Title database Id in the form */
	private Title getInternalTitle(TitleForm form) {
		long id = form.getId();
		return TitleFacade.findTitle(id);
	}
	
	/* Get the Title from an external source using the information in the form */
	private Title getExternalTitle(TitleForm form) {
		/* Build the external keys */
		String externalKey = form.getExternalKey();
		TitleExternalKeySerializer keySerializer = TitleExternalKeySerializer.newInstance();
		Map<String, String> metadataKeys = keySerializer.deserialize(externalKey);

		/* Get the external title */
		ServiceRegistry registry = ServiceRegistry.getDefault();
		ITitleService titleService = registry.lookup(ITitleService.class);
		return titleService.getExternalTitle(form.getType(), form.getAssetDB(), metadataKeys);
	}

	@Deprecated
	protected void save(TitleForm form, Title rootTitle) throws Exception {
		/*List<Title> titlesWithUpdatedAsset = new ArrayList<Title>(0);
		List<Title> titlesWithMappedAsset = new ArrayList<Title>(0);
		boolean newMetadataFileMapped = false;

		TitleFacade.beginAssetsManagerTx();
		
		boolean saveSuccessful = false;
		try {
			//copy asset locations from ui form
			titlesWithUpdatedAsset = handleChangeInAssetLocations(form.getTitlesData(), rootTitle);

			newMetadataFileMapped = TitleHelper.newFileMapped(rootTitle.getMetadataLocation(),
					form.getMetadataLocation());
			rootTitle.setMetadataLocation(form.getMetadataLocation());

			if(newMetadataFileMapped) {
				//overwrite metadata from metadata file
				Title parsedMetadata =
					TitleFacade.parseMetadata(form.getType(), rootTitle.getMetadataLocation());
				TitleFacade.replaceMetadata(parsedMetadata, rootTitle);

				//map unmapped assets
				titlesWithMappedAsset = TitleFacade.mapAssets(rootTitle);
			}
			else {
				TitleHelper.copyMetadata(form.getTitlesData(), rootTitle);
			}

			TitleFacade.save(rootTitle);
			saveSuccessful = true;
		} finally {
			if(saveSuccessful) {
				TitleFacade.commitAssetsManagerTx();
			} else {
				try {
					TitleFacade.rollbackAssetsManagerTx();
				} catch(Exception e) {
					logger.error("Title: " + rootTitle
							+ " - Rolling back failed. | " + e.getMessage(), e);
				}
			}
		}

		form.setId(rootTitle.getId());
		
		//send progress status
		if(newMetadataFileMapped) {
			TitleFacade.sendMetadataReceivedStatus(rootTitle);
		}
		for(Title title : titlesWithUpdatedAsset) {
			TitleFacade.sendAssetReceivedStatus(rootTitle, title.getName());
		}
		for(Title title : titlesWithMappedAsset) {
			TitleFacade.sendAssetReceivedStatus(rootTitle, title.getName());
		}*/
	}
	
	/*
	 * Maps/unmaps asset locations based on the form titlesData.
	 * Returns list of titles for which the asset location has been modified to a non-null value.
	 */
	@Deprecated
	private List<Title> handleChangeInAssetLocations(List<TitleData> titlesData, Title rootTitle)
														throws SANManagementException, IOException {
		/*
		//a list to hold titles that has a new asset mapped 
		List<Title> titlesWithUpdatedFiles = new ArrayList<Title>();
		for(TitleData td : titlesData) {
			Title t = rootTitle.getTitle(td.getName());
			if(t != null) {
				Variable tdVar = td.getVariableByName(TitleHelper.ASSET_LOCATION_NAME);
				if(tdVar != null) {
					String currentLocation = TitleHelper.trim(t.getAssetLocation());
					String newLocation = tdVar.getValue();
					
					boolean existingFileUnmapped = false;
					boolean newFileMapped = false;
					
					if(currentLocation == null) {
						if(newLocation != null) {
							//new map
							newFileMapped = true;
						}
					} else {
						if(newLocation != null) {
							if(!TitleHelper.equals(currentLocation, newLocation)) {
								//remap
								existingFileUnmapped = true;
								newFileMapped = true;
							}
						} else {
							//unmap
							existingFileUnmapped = true;
						}
					}
					
					logger.debug("Title: " + t.getName()
							+ " | Existing File Unmapped: " + existingFileUnmapped
							+ " | New File Mapped: " + newFileMapped);
					
					if(existingFileUnmapped) {
						if(TitleFacade.isInMappedFilesDirectory(currentLocation)) {
							TitleFacade.moveToUnmappedFilesDirectory(currentLocation);
						}
					}
					
					if(newFileMapped) {
						if(TitleFacade.isInUnmappedFilesDirectory(newLocation)) {
							newLocation = TitleFacade.moveToMappedFilesDirectory(newLocation);
						}
						titlesWithUpdatedFiles.add(t);
					}

					t.setAssetLocation(newLocation);
				}
			}
		}
		
		return titlesWithUpdatedFiles;
		*/
		return null;
	}
	
}
