package org.eclipse.emf.henshin.variability.configuration.ui.providers;

import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.henshin.model.Rule;
import org.eclipse.emf.henshin.variability.wrapper.VariabilityFactory;
import org.eclipse.emf.henshin.variability.wrapper.VariabilityRule;

import configuration.Configuration;
import configuration.ConfigurationFactory;
import configuration.Favorite;
import configuration.Feature;
import configuration.impl.ConfigurationFactoryImpl;

/**
 * This class helps managing configurations.
 * 
 * @author Stefan Schulz
 *
 */
public class ConfigurationProvider {

	private final static String REGEX = "def\\((.*?)\\)";

	private Map<Rule, Configuration> currentConfigurations = new HashMap<Rule, Configuration>();
	private Map<Rule, Set<Favorite>> favoriteConfigurations = new HashMap<Rule, Set<Favorite>>();
	private static ConfigurationProvider vpProvider = new ConfigurationProvider();
	ConfigurationFactory fac = ConfigurationFactory.eINSTANCE;

	public static ConfigurationProvider getInstance() {
		return vpProvider;
	}

	public Configuration getConfiguration(Rule rule) {
		Configuration result = null;

		if (currentConfigurations.containsKey(rule)) {
			result = currentConfigurations.get(rule);
		} else {
			result = createConfiguration(rule);
		}

		return result;
	}
	
	public Configuration getConfiguration(Favorite favorite) {
		Configuration result = null;
		
		result = fac.createConfiguration(favorite);
		result.setRule(favorite.getRule());
		currentConfigurations.put(result.getRule(), result);

		return result;
	}

	public Favorite addConfigurationToFavorites(Rule rule, String name, Configuration configuration) {
		if (favoriteConfigurations.get(rule) == null) {
			favoriteConfigurations.put(rule, new LinkedHashSet<Favorite>());
		}
		Favorite favorite = fac.createFavorite(configuration);
		favorite.setRule(rule);
		favorite.setName(name);

		favoriteConfigurations.get(rule).add(favorite);
		return favorite;
	}
	
	private Favorite findMatchingFavorite(Configuration configuration) {
		Favorite result = null;
		Set<Favorite> ruleFavorites = favoriteConfigurations.get(configuration.getRule());

		if (ruleFavorites != null) {
			for (Favorite favorite : ruleFavorites) {
				if (favorite.getFeatures().size() == configuration.getFeatures().size()) {
					int matches = 0;
					 /* 
					  * TODO: This needs to be improved
					  */
					for (int i = favorite.getFeatures().size() - 1; i >= 0; i--) {
						Feature favVP = favorite.getFeatures().get(i);
						Feature conVP = configuration.getFeatures().get(i);

						if (conVP.getName().equals(favVP.getName()) && conVP.getBinding() == favVP.getBinding()) {
							matches++;
						}
					}
					if (matches == configuration.getFeatures().size()) {
						result = favorite;
						break;
					}
				}
			}
		}
		return result;
	}
	
	public void clearFavorites(Configuration configuration) {
		Set<Favorite> favorites = favoriteConfigurations.get(configuration.getRule());
		if (favorites != null) {
			favorites.clear();
		}
	}
	
	public void removeConfigurationFromFavorites(Configuration configuration) {
		Favorite favorite = findMatchingFavorite(configuration);
		
		if(favorite != null) {
			favoriteConfigurations.get(configuration.getRule()).remove(favorite);
		}
	}

	public boolean isFavorite(Configuration configuration) {
		return findMatchingFavorite(configuration) != null;
	}
	
	public Favorite findFavorite(Configuration configuration) {
		return findMatchingFavorite(configuration);
	}

	public void addFavorites(Rule rule, Set<Favorite> favoritesSet) {
		favoriteConfigurations.put(rule, favoritesSet);
	}

	public Set<Favorite> getFavorites(Rule rule) {
		return favoriteConfigurations.get(rule);
	}

	private Configuration createConfiguration(Rule rule) {
		Configuration result = null;

		if (rule != null) {
			VariabilityRule varRule = VariabilityFactory.createVariabilityRule(rule);
			ConfigurationFactory fac = ConfigurationFactoryImpl.init();
			result = fac.createConfiguration();
			result.setRule(rule);
			String featureModel = varRule.getFeatureModel();
			EList<Feature> variabilityPoints = result.getFeatures();

			if(varRule.getFeatures() != null) {
				for(String variabilityPointName : varRule.getFeatures()) {
					Feature vp = fac.createFeature();
					vp.setName(variabilityPointName);
					variabilityPoints.add(vp);
				}
			} else if (featureModel != null && !featureModel.isEmpty()) {
				Matcher match = Pattern.compile(REGEX).matcher(featureModel);
				while (match.find()) {
					for (int i = 1; i <= match.groupCount(); i++) {
						Feature vp = fac.createFeature();
						vp.setName(match.group(i));
						variabilityPoints.add(vp);
					}
				}
			}
			currentConfigurations.put(rule, result);
		}

		return result;
	}
}
