/*=============================================================================#
 # Copyright (c) 2005, 2021 Stephan Wahlbrink and others.
 # 
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License 2.0 which is available at
 # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
 # which is available at https://www.apache.org/licenses/LICENSE-2.0.
 # 
 # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 # 
 # Contributors:
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.ltk.ui.sourceediting.presentation;

import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullLateInit;

import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.jface.text.rules.IRule;
import org.eclipse.jface.text.rules.IToken;
import org.eclipse.jface.text.rules.IWordDetector;
import org.eclipse.jface.text.rules.WordRule;

import org.eclipse.statet.jcommons.collections.ImList;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;

import org.eclipse.statet.ecommons.preferences.core.PreferenceAccess;
import org.eclipse.statet.ecommons.text.ui.presentation.AbstractRuleBasedScanner;
import org.eclipse.statet.ecommons.text.ui.presentation.ITextPresentationConstants;
import org.eclipse.statet.ecommons.text.ui.presentation.TextStyleManager;
import org.eclipse.statet.ecommons.ui.ISettingsChangedHandler;

import org.eclipse.statet.ltk.issues.core.Issues;


/**
 * Scanner for comments. Provides support for task tags.
 */
@NonNullByDefault
public class CommentScanner extends AbstractRuleBasedScanner implements ISettingsChangedHandler {
	
	
	private static class TaskTagDetector implements IWordDetector {
		
		@Override
		public boolean isWordStart(final char c) {
			return Character.isLetterOrDigit(c);
		}
		
		@Override
		public boolean isWordPart(final char c) {
			return Character.isLetterOrDigit(c);
		}
	}
	
	private static class TaskTagRule extends WordRule {
		
		private final IToken token;
		
		public TaskTagRule(final IToken token, final IToken defaultToken) {
			super(new TaskTagDetector(), defaultToken);
			this.token= token;
		}
		
		public void setKeywords(final ImList<String> tags) {
			this.fWords.clear();
			for (final String tag : tags) {
				addWord(tag, this.token);
			}
		}
	}
	
	
	private final String prefQualifier;
	private final PreferenceAccess prefs;
	
	private TaskTagRule taskTagRule= nonNullLateInit();
	
	private final String commentTokenKey;
	private final String taskTokenKey;
	
	
	public CommentScanner(final TextStyleManager<?> textStyles,
			final String commentTokenKey, final String taskTokenKey,
			final String prefQualifier, final PreferenceAccess prefs) {
		super(textStyles);
		
		this.commentTokenKey= commentTokenKey;
		this.taskTokenKey= taskTokenKey;
		initRules();
		
		this.prefQualifier= prefQualifier;
		this.prefs= prefs;
		loadTaskTags();
	}
	
	public CommentScanner(final TextStyleManager<?> textStyles,
			final String commentTokenKey, final String taskTokenKey,
			final PreferenceAccess prefs) {
		this(textStyles, commentTokenKey, taskTokenKey, PREF_QUALIFIER, prefs);
	}
	
	
	@Override
	protected void createRules(final List<IRule> rules) {
		final IToken defaultToken= getToken(this.commentTokenKey);
		final IToken taskToken= getToken(this.taskTokenKey);
		
		setDefaultReturnToken(defaultToken);
		
		// Add rule for Task Tags.
		this.taskTagRule= new TaskTagRule(taskToken, defaultToken);
		rules.add(this.taskTagRule);
	}
	
	
	// TODO
	private static final String GROUP_ID= "statet.task_tags"; //$NON-NLS-1$
	private static final String PREF_QUALIFIER= "org.eclipse.statet.ide.core/managment"; //$NON-NLS-1$
	
	@Override
	public void handleSettingsChanged(final Set<String> groupIds, final Map<String, Object> options) {
		if (groupIds.contains(GROUP_ID)) {
			loadTaskTags();
			options.put(ITextPresentationConstants.SETTINGSCHANGE_AFFECTSPRESENTATION_KEY, Boolean.TRUE);
		}
	}
	
	private void loadTaskTags() {
		final var taskTags= Issues.loadTaskTags(this.prefQualifier, this.prefs);
		this.taskTagRule.setKeywords(Issues.getKeywords(taskTags));
	}
	
}
