package com.tandbergtv.watchpoint.pmm.assetlist;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.Session;

import com.tandbergtv.cms.portal.util.transaction.Transactional;
import com.tandbergtv.watchpoint.pmm.dao.hibernate.HibernateContext;
import com.tandbergtv.watchpoint.pmm.entities.AssetList;
import com.tandbergtv.watchpoint.pmm.entities.Title;
import com.tandbergtv.watchpoint.pmm.title.ITitlePersistenceService;
import com.tandbergtv.workflow.core.service.ServiceRegistry;

public class AssetListPersistenceService<E extends AssetList> implements IAssetListPersistenceService<E> {

	private Logger logger = Logger.getLogger(this.getClass());
	private String serviceName;

	public AssetListPersistenceService(String serviceName) {
		this.serviceName = serviceName;
	}
	
	@Transactional
	public void delete(Serializable id) {
		try {
			delete(get(id));
		} catch (Exception e) {
			throw new RuntimeException("Failed to delete enity with id: " + id, e);
		}
	}

	@Transactional
	public void delete(E entity) {
		try {
			Session session = getSession();

			entity.setIsActive(false);
			entity.removeTitles();

			session.saveOrUpdate(entity);
			logger.debug("Deleted entity " + entity);
		} catch (Exception e) {
			throw new RuntimeException("Failed to delete " + entity, e);
		}
	}

	@SuppressWarnings("unchecked")
	@Transactional
	public E get(Serializable id) {
		Session session = getSession();
		return (E) session.load(AssetList.class, id);
	}

	@Transactional
	@Override
	public E save(E entity) {
		try {
			Session session = getSession();
			session.saveOrUpdate(entity);
			logger.debug("Updated: " + entity);
			return entity;
		} catch (Exception e) {
			throw new RuntimeException("Failed to save " + entity, e);
		}
	}

	public String getServiceName() {
		return serviceName;
	}

	public void start() { }

	public void stop() { }

	@Override
	@Transactional
	public void addTitles(long assetListId, List<Long> titleIds) {
		E entity = get(assetListId);
		List<Title> titlesToAdd = new ArrayList<Title>();
		for(long id : titleIds) {
			titlesToAdd.add(getTitlePersistenceService().get(id));
		}
		entity.addTitles(titlesToAdd);
		save(entity);
	}	

	@Override
	@Transactional
	public void removeTitles(long assetListId, List<Long> titleIds) {
		E entity = get(assetListId);
		List<Title> titlesToRemove = new ArrayList<Title>();
		for(Title t : entity.getTitles()) {
			if(titleIds.contains(t.getId())) {
				titlesToRemove.add(t);
			}
		}
		entity.removeTitles(titlesToRemove);
		save(entity);
	}

	private ITitlePersistenceService getTitlePersistenceService() {
		return ServiceRegistry.getDefault().lookup(ITitlePersistenceService.class);
	}
	
	protected Session getSession() {
		return HibernateContext.getContext().getCurrentSession();
	}

}
