package com.tandbergtv.metadatamanager;

import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate3.HibernateTemplate;

import com.tandbergtv.metadatamanager.exception.MetadataException;
import com.tandbergtv.metadatamanager.exception.SearchException;
import com.tandbergtv.metadatamanager.model.RuleSet;

/**
 * This is a hibernate implementiona of the Rule Manager DAO interface.
 * 
 */
public class RuleManagerDAOImpl implements RuleManagerDAO {

	/* wrapper over the session factory */
	private HibernateTemplate template;

	/* logger */
	private static final Logger logger = Logger
			.getLogger(RuleManagerDAOImpl.class);

	/**
	 * @return the template
	 */
	public HibernateTemplate getTemplate() {
		return template;
	}

	/**
	 * @param template
	 *            the template to set
	 */
	public void setTemplate(HibernateTemplate template) {
		this.template = template;
	}

	@Override
	public void deleteRuleSet(long id) throws SearchException {
		getTemplate().delete(new RuleSet(id));
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<String> getAllRuleSetNames(String spec) throws MetadataException {
		List<String> result = new ArrayList<String>();
		DetachedCriteria criteria = DetachedCriteria.forClass(RuleSet.class);
		criteria.add(Restrictions.eq("spec", spec));
		List<RuleSet> rsList = getTemplate().findByCriteria(criteria);
		for(RuleSet rs : rsList)
			result.add(rs.getName());
		return result;
	}

	@Override
	public RuleSet getRuleSet(long id) throws SearchException {
		RuleSet rs = (RuleSet) getTemplate().get(RuleSet.class, id);
		if (rs == null) {
			throw new RuntimeException("Could not get rule set with id: " + id);
		}
		return rs;
	}

	@SuppressWarnings("unchecked")
	@Override
	public RuleSet lookupRuleSet(String name, String spec) throws SearchException {
		DetachedCriteria criteria = DetachedCriteria.forClass(RuleSet.class);
		criteria.add(Restrictions.eq("spec", spec));
		criteria.add(Restrictions.eq("name", name));
		List<RuleSet> rsList = getTemplate().findByCriteria(criteria);
		if (rsList == null || rsList.isEmpty()) {
			throw new RuntimeException("Could not get rule set with name: "
					+ name);
		}
		return rsList.get(0);
	}

	@Override
	public RuleSet saveRuleSet(RuleSet ruleSet) throws MetadataException {
		try {
			getTemplate().saveOrUpdate(ruleSet);
			return ruleSet;
		} catch (DataAccessException e) {
			throw new MetadataException(e.getMessage(), e);
		}
	}
}
