package com.cflint.config;

import java.util.ArrayList;
import java.util.List;

import com.cflint.config.CFLintPluginInfo.PluginInfoRule;
import com.cflint.config.CFLintPluginInfo.PluginInfoRule.PluginMessage;
import com.cflint.plugins.CFLintScanner;

/**
 * Combines information from the config.xml and the core CFLint information and
 * provides utility functions
 * 
 * It only includes the Rules that are matched by the include/exclude section if one of them is present. 
 */
public class ConfigRuntime extends CFLintConfig {

	public ConfigRuntime() {
		
	}
	public ConfigRuntime(final CFLintConfig config, final CFLintPluginInfo pluginInfo) {
		final List<PluginInfoRule> rules = new ArrayList<PluginInfoRule>();
		
		if(config !=null){
			includes.addAll(config.getIncludes());
			excludes.addAll(config.getExcludes());
			rules.addAll(config.getRules());
		}
		for (final PluginInfoRule rule : pluginInfo.getRules()) {
			if (!rules.contains(rule)) {
				rules.add(rule);
			}
		}

		if(config !=null){
			// If includes is specified, load *only* those messages
			if (!config.getIncludes().isEmpty()) {
				for (final PluginInfoRule rule : rules) {
					// Include the rule if at least one of the messages is included.
					for (PluginMessage msg : rule.getMessages()) {
						if (config.getIncludes().contains(msg)) {
							getRules().add(rule);
							break;
						}
					}
				}
			} else {// Otherwise load all considering the excludes.
				for (final PluginInfoRule rule : rules) {
					// Exclude the rule if ALL of the messages are excluded.
					boolean excluded = true;
					for (PluginMessage msg : rule.getMessages()) {
						excluded = excluded && config.getExcludes().contains(msg);
					}
					if (!excluded) {
						getRules().add(rule);
					}
				}
			}
		}else{
			getRules().addAll(rules);
		}
	}

	public boolean isIncludeMessage(final String messageCode) {
		return isIncludeMessage(new PluginMessage(messageCode));
	}
	public boolean isIncludeMessage(final PluginMessage message) {
		if(!includes.isEmpty()){
			return includes.contains(message);
		}else{
			return !excludes.contains(message);
		}
	}
	
	public PluginInfoRule getRuleByClass(Class<?> clazz){
		final String className = clazz.getSimpleName();
		for (final PluginInfoRule rule : getRules()) {
			if (rule.getName().equals(className) || className.equals(rule.getClassName())) {
				return rule;
			}
		}
		return null;
	}
	public PluginInfoRule getRuleForPlugin(CFLintScanner plugin) {
		for (final PluginInfoRule rule : getRules()) {
			if (rule.getPluginInstance() == plugin) {
				return rule;
			}
		}
		return getRuleByClass(plugin.getClass());
	}
}

@@ -1358,24 +1358,172 @@
 ns(msg)) %7B%0D%0A
+%09%09%09%09%09%09%09for (PluginMessage cfgMsg : config.getIncludes()) %7B%0D%0A%09%09%09%09%09%09%09%09if (cfgMsg.equals(msg)) %7B%0D%0A%09%09%09%09%09%09%09%09%09merge(cfgMsg, msg);%0D%0A%09%09%09%09%09%09%09%09%7D%0D%0A%09%09%09%09%09%09%09%7D%0D%0A%0D%0A
 %09%09%09%09%09%09%09getRu
@@ -2027,24 +2027,476 @@
 %0A%09%09%7D%0D%0A%09%7D%0D%0A%0D%0A
+%09/*%0D%0A%09 * Apply the configuration to the existing rule. Overlay it.%0D%0A%09 */%0D%0A%09private void merge(PluginMessage cfgMsg, PluginMessage msg) %7B%0D%0A%09%09if (!isEmpty(cfgMsg.getMessageText())) %7B%0D%0A%09%09%09msg.setMessageText(cfgMsg.getMessageText());%0D%0A%09%09%7D%0D%0A%09%09if (!isEmpty(cfgMsg.getSeverity())) %7B%0D%0A%09%09%09msg.setSeverity(cfgMsg.getSeverity());%0D%0A%09%09%7D%0D%0A%09%7D%0D%0A%0D%0A%09private boolean isEmpty(String messageText) %7B%0D%0A%09%09return messageText == null %7C%7C messageText.trim().length() == 0;%0D%0A%09%7D%0D%0A%0D%0A
 %09public bool

support overriding message and severity within the include config