package org.antlr.intellij.plugin.configdialogs;

import com.intellij.openapi.fileTypes.WildcardFileNameMatcher;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.xmlb.annotations.Property;
import org.antlr.intellij.plugin.parsing.CaseChangingStrategy;
import org.jetbrains.annotations.Nullable;

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

/**
 * Stores settings related to code generation per grammar file.
 */
public class ANTLRv4GrammarPropertiesStore {

	static final ANTLRv4GrammarProperties DEFAULT_GRAMMAR_PROPERTIES = initDefaultGrammarProperties();

	@Property
	private List<ANTLRv4GrammarProperties> perGrammarGenerationSettings = new ArrayList<>();

	public void add(ANTLRv4GrammarProperties properties) {
		perGrammarGenerationSettings.add(properties);
	}

	public ANTLRv4GrammarProperties getGrammarProperties(String grammarFile) {
		ANTLRv4GrammarProperties grammarSettings = findSettingsForFile(grammarFile);

		if ( grammarSettings==null ) {
			ANTLRv4GrammarProperties projectSettings = findSettingsForFile("*");

			if ( projectSettings==null ) {
				return ANTLRv4GrammarPropertiesStore.DEFAULT_GRAMMAR_PROPERTIES;
			}

			return projectSettings;
		}

		return grammarSettings;
	}

	public ANTLRv4GrammarProperties getOrCreateGrammarProperties(String grammarFile) {

		ANTLRv4GrammarProperties properties = getGrammarProperties(grammarFile);

		if ( Objects.equals(properties.fileName, grammarFile) ) {
			return properties;
		}

		ANTLRv4GrammarProperties newProperties = new ANTLRv4GrammarProperties(properties);
		newProperties.fileName = grammarFile;

		add(newProperties);

		return newProperties;
	}

	@Nullable
	private ANTLRv4GrammarProperties findSettingsForFile(String fileName) {
		for (ANTLRv4GrammarProperties settings : perGrammarGenerationSettings) {
			if (settings.fileName.equals(fileName)) {
				return settings;
			}
		}

		for (ANTLRv4GrammarProperties settings : perGrammarGenerationSettings) {
			WildcardFileNameMatcher wildcardFileNameMatcher = new WildcardFileNameMatcher(settings.fileName);
			if (wildcardFileNameMatcher.acceptsCharSequence(fileName)) {
				return settings;
			}
		}

		return null;
	}
	public static ANTLRv4GrammarProperties getGrammarProperties(Project project, VirtualFile grammarFile) {
		return getGrammarProperties(project, grammarFile.getPath());
	}

	/**
	 * Defaults to settings defined in the project if they exist, or to empty settings.
	 */
	public static ANTLRv4GrammarProperties getGrammarProperties(Project project, String grammarFile) {
		ANTLRv4GrammarPropertiesStore store = ANTLRv4GrammarPropertiesComponent.getInstance(project).getState();
		return store.getGrammarProperties(grammarFile);
	}

	/**
	 * Get the properties for this grammar, or create a new properties object derived from the project settings if
	 * they exist, or from the default empty settings otherwise.
	 */
	public static ANTLRv4GrammarProperties getOrCreateGrammarProperties(Project project, String grammarFile) {
		ANTLRv4GrammarPropertiesStore store = ANTLRv4GrammarPropertiesComponent.getInstance(project).getState();
		return store.getOrCreateGrammarProperties(grammarFile);
	}

	private static ANTLRv4GrammarProperties initDefaultGrammarProperties() {
		ANTLRv4GrammarProperties defaultSettings = new ANTLRv4GrammarProperties();

		defaultSettings.fileName = "**";
		defaultSettings.autoGen = true;
		defaultSettings.outputDir = "";
		defaultSettings.libDir = "";
		defaultSettings.encoding = "";
		defaultSettings.pkg = "";
		defaultSettings.language = "";
		defaultSettings.generateListener = true;
		defaultSettings.generateVisitor = true;
		defaultSettings.caseChangingStrategy = CaseChangingStrategy.LEAVE_AS_IS;

		return defaultSettings;
	}
}

@@ -43,16 +43,63 @@
 alogs;%0A%0A
+import com.intellij.openapi.diagnostic.Logger;%0A
 import c
@@ -598,16 +598,122 @@
 tore %7B%0A%0A
+%09private static final Logger logger = Logger.getInstance(ANTLRv4GrammarPropertiesStore.class.getName());%0A%0A
 %09static 
@@ -1442,37 +1442,38 @@
 Settings;%0A%09%7D%0A%0A%09p
-ublic
+rivate
  ANTLRv4GrammarP
@@ -2184,16 +2184,221 @@
 ings) %7B%0A
+%09%09%09if (matchesWildcardPattern(fileName, settings)) %7B%0A%09%09%09%09return settings;%0A%09%09%09%7D%0A%09%09%7D%0A%0A%09%09return null;%0A%09%7D%0A%0A%09private boolean matchesWildcardPattern(String fileName, ANTLRv4GrammarProperties settings) %7B%0A%09%09try %7B%0A
 %09%09%09Wildc
@@ -2565,36 +2565,135 @@
 %09return 
-settings;%0A%09%09%09%7D
+true;%0A%09%09%09%7D%0A%09%09%7D catch (Exception e)%7B%0A%09%09%09logger.warn(%22Unable to check if wildcard matches file name: %22+fileName, e);
 %0A%09%09%7D%0A
-%0A
 %09%09return
@@ -2693,25 +2693,27 @@
 %09return 
-null
+false
 ;%0A%09%7D%0A
+%0A
 %09public 

Add try-catch when checking wildcard path match