package com.tandbergtv.metadatamanager.specimpl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.tandbergtv.metadatamanager.RuleManagerDAO;
import com.tandbergtv.metadatamanager.exception.MetadataException;
import com.tandbergtv.metadatamanager.exception.SearchException;
import com.tandbergtv.metadatamanager.model.Rule;
import com.tandbergtv.metadatamanager.model.RuleSet;
import com.tandbergtv.metadatamanager.spec.IRuleManager;

/**
 * Base class for most rule managers.
 * 
 * @author nicholas
 * 
 */
public abstract class RuleManagerBase implements IRuleManager {

	protected String spec;
	private RuleManagerDAO ruleManagerDAO;
	private Map<String, Boolean> defaultRuleSet;

	public String getSpec() {
		return spec;
	}

	public void setSpec(String spec) {
		this.spec = spec;
	}

	public RuleManagerDAO getRuleManagerDAO() {
		return ruleManagerDAO;
	}

	public void setRuleManagerDAO(RuleManagerDAO ruleManagerDAO) {
		this.ruleManagerDAO = ruleManagerDAO;
	}

	public Map<String, Boolean> getDefaultRuleSet() {
		return defaultRuleSet;
	}

	public void setDefaultRuleSet(Map<String, Boolean> defaultRuleSet) {
		this.defaultRuleSet = defaultRuleSet;
	}
	
	// update/create - returns rule set
	public Map<String, Boolean> saveRuleSet(String nameOfRuleSet, Map<String, Boolean> ruleSet) throws MetadataException {
		RuleSet savedRuleSet = null;
		try {
			savedRuleSet = ruleManagerDAO.lookupRuleSet(nameOfRuleSet, spec);
		} catch (Exception e) {
			// ignore exceptions
		}
		RuleSet rs = new RuleSet();
		if (savedRuleSet != null) {
			rs = new RuleSet(savedRuleSet.getId());
		}
		rs.setName(nameOfRuleSet);
		rs.setSpec(spec);
		for (Map.Entry<String, Boolean> entry : ruleSet.entrySet()) {
			Rule r = new Rule();
			r.setXpath(entry.getKey());
			r.setIsRequired(entry.getValue());
			rs.addRule(r);
		}
		try {
			ruleManagerDAO.saveRuleSet(rs);
		} catch (MetadataException e) {
			throw new MetadataException(e.getMessage());
		}
		return ruleSet;
	}

	// get - returns rule set
	public Map<String, Boolean> getRuleSet(String nameOfRuleSet) {
		Map<String, Boolean> map = new HashMap<String, Boolean>();
		try {
			Set<Rule> rules = ruleManagerDAO.lookupRuleSet(nameOfRuleSet, spec).getRules();
			for(Rule rule : rules) {
				map.put(rule.getXpath(), rule.getIsRequired());
			}
		} catch (SearchException e) {
			e.printStackTrace();
		}
		return map;
	}

	// get default - returns rule set
	public Map<String, Boolean> getRuleSet() {
		return defaultRuleSet;
	}

	// get all - returns list of rule set names
	public List<String> getAllRuleSets() {
		try {
			return ruleManagerDAO.getAllRuleSetNames(spec);
		} catch (MetadataException e) {
			e.printStackTrace();
		}
		return null;
	}

	// delete
	public void deleteRuleSet(String nameOfRuleSet) {
		try {
			long id = ruleManagerDAO.lookupRuleSet(nameOfRuleSet, spec).getId();
			ruleManagerDAO.deleteRuleSet(id);
		} catch (SearchException e) {
			e.printStackTrace();
		}
	}
}
