/*=============================================================================#
 # Copyright (c) 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.issues.core;

import java.util.List;

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

import org.eclipse.statet.ecommons.preferences.core.Preference.EnumListPref;
import org.eclipse.statet.ecommons.preferences.core.Preference.StringArrayPref;
import org.eclipse.statet.ecommons.preferences.core.PreferenceAccess;

import org.eclipse.statet.ltk.issues.core.impl.BasicTaskTag;


@NonNullByDefault
public final class Issues {
	
	
	public static final String TASK_TAG_KEYWORD_PREF_KEY= "TaskTags.keyword"; //$NON-NLS-1$
	public static final String TASK_TAG_PRIORITY_PREF_KEY= "TaskTags.priority"; //$NON-NLS-1$
	
	
	private static StringArrayPref createKeywordPref(final String qualifier) {
		return new StringArrayPref(qualifier, TASK_TAG_KEYWORD_PREF_KEY);
	}
	
	private static EnumListPref<TaskPriority> createPriorityPref(final String qualifier) {
		return new EnumListPref<>(qualifier, TASK_TAG_PRIORITY_PREF_KEY, TaskPriority.class);
	}
	
	
	public static ImList<TaskTag> loadTaskTags(final String qualifier, final PreferenceAccess prefs) {
		final @NonNull String[] keywords= prefs.getPreferenceValue(createKeywordPref(qualifier));
		final List<TaskPriority> priorities= prefs.getPreferenceValue(createPriorityPref(qualifier));
		
		if (keywords.length == priorities.size()) {
			final var array= new @NonNull TaskTag[keywords.length];
			for (int i= 0; i < array.length; i++) {
				array[i]= new BasicTaskTag(keywords[i], priorities.get(i));
			}
			return ImCollections.newList(array);
		}
		else {
			return ImCollections.emptyList();
		}
	}
	
	public static ImList<String> getKeywords(final ImList<TaskTag> taskTags) {
		final var array= new @NonNull String[taskTags.size()];
		for (int i= 0; i < array.length; i++) {
			array[i]= taskTags.get(i).getKeyword();
		}
		return ImCollections.newList(array);
	}
	
	
}
