package com.tandbergtv.metadatamanager.util;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.hibernate.Session;

import com.tandbergtv.metadatamanager.model.Asset;
import com.tandbergtv.metadatamanager.model.Field;
import com.tandbergtv.metadatamanager.model.FieldRevision;
import com.tandbergtv.metadatamanager.model.File;
import com.tandbergtv.metadatamanager.model.Group;
import com.tandbergtv.metadatamanager.model.IAssetVisitor;
import com.tandbergtv.metadatamanager.model.Item;
import com.tandbergtv.metadatamanager.model.NextRevision;
import com.tandbergtv.metadatamanager.model.Relation;

/**
 * Hibernate has this problem where instanceof on lazily loaded objects does not
 * work correctly. this util class takes the lazily loaded asset object does the
 * appropriate instanceof's and returns the asset that can be used by the caller
 * with instanceof
 * 
 * @author vgoyal
 * 
 */
public class AssetUtil {
	public Asset convertedAsset;

	/**
	 * deletes all fields wth a blank value
	 * 
	 * @param asset
	 * @return
	 */
	public static Asset deleteEmptyFields(Asset asset) {
		if (asset != null) {
			ArrayList<Field> blankFields = new ArrayList<Field>();
			for (Field f : asset.getFields()) {
				if (f.getValue()!=null && f.getValue().equals("")) {
					blankFields.add(f);
				}
			}
			asset.getFields().removeAll(blankFields);

			for (Relation r : asset.getRelations()) {
				deleteEmptyFields(r.getTargetAsset());
			}
		}
		return asset;
	}

	public Asset unWrap(Asset a) {
		IAssetVisitor visitor = null;
		if (a.isInstance(Group.class)) {
			visitor = new IAssetVisitor() {
				@Override
				public void unWrap(Asset a) {
					convertedAsset = (Group) a;
				}
			};
		} else if (a.isInstance(Item.class)) {
			visitor = new IAssetVisitor() {
				@Override
				public void unWrap(Asset a) {
					convertedAsset = (Item) a;
				}
			};
		} else if (a.isInstance(File.class)) {
			visitor = new IAssetVisitor() {
				@Override
				public void unWrap(Asset a) {
					convertedAsset = (File) a;
				}
			};
		}
		a.accept(visitor);
		return convertedAsset;
	}
	
	/**
	 * Before saving an Asset to DB for the 1st time, we need to call this
	 * method to copy all its fields to fieldRevisions
	 * @param asset
	 */
	public static void copyFieldsToFieldRevisions(Asset asset, NextRevision nextRevision){
		List<Field> fields = asset.getFields();
		List<FieldRevision> fieldRevisions = asset.getFieldRevisions();
		if(!isCollectionEmpty(fields) && isCollectionEmpty(fieldRevisions)){
			fieldRevisions = new ArrayList<FieldRevision>();
			for(Field field: fields){
				FieldRevision fieldRevision = new FieldRevision(field, nextRevision);
				asset.addFieldRevision(fieldRevision, nextRevision);
			}
		}
		for(Relation currentRelation: asset.getRelations()){
			copyFieldsToFieldRevisions(currentRelation.getTargetAsset(), nextRevision);
		}
		
	}
	

	public static boolean isCollectionEmpty(Collection<?> anyCollection){
		return (anyCollection==null || anyCollection.size() ==0);
	}

	public static void evictAssetTree(Asset asset, Session session) {
		for (Relation targetRelation : asset.getRelations()) {
			evictAssetTree(targetRelation.getTargetAsset(), session);
		}
		session.evict(asset);
	}
}
