/*=============================================================================#
 # 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.ArrayList;
import java.util.Collection;

import org.eclipse.statet.jcommons.collections.ImCollections;
import org.eclipse.statet.jcommons.collections.ImIdentitySet;
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.jcommons.lang.Nullable;

import org.eclipse.statet.ltk.core.Ltk;
import org.eclipse.statet.ltk.core.WorkingContext;


@NonNullByDefault
public class IssueTypeSet {
	
	
	public final static class ProblemTypes {
		
		private final String errorType;
		private final String warningType;
		private final String infoType;
		
		public ProblemTypes(final String errorType, final String warningType, final String infoType) {
			this.errorType= errorType;
			this.warningType= warningType;
			this.infoType= infoType;
		}
		
		public ProblemTypes(final String type) {
			this.errorType= type;
			this.warningType= type;
			this.infoType= type;
		}
		
		public String getType(final int priority) {
			switch (priority) {
			case Problem.SEVERITY_ERROR:
				return this.errorType;
			case Problem.SEVERITY_WARNING:
				return this.warningType;
			default:
				return this.infoType;
			}
		}
		
	}
	
	public static class ProblemTypeDef {
		
		private final String id;
		
		private final @Nullable ProblemTypes persistenceTypes;
		private final @Nullable ProblemTypes editorTypes;
		
		public ProblemTypeDef(final String id,
				@Nullable final ProblemTypes persistenceTypes, @Nullable final ProblemTypes editorTypes) {
			this.id= id;
			this.persistenceTypes= persistenceTypes;
			this.editorTypes= editorTypes;
		}
		
		public String getId() {
			return this.id;
		}
		
		public @Nullable ProblemTypes getTypes(final WorkingContext context) {
			if (context == Ltk.PERSISTENCE_CONTEXT) {
				return this.persistenceTypes;
			}
			if (context == Ltk.EDITOR_CONTEXT) {
				return this.editorTypes;
			}
			return null;
		}
		
	}
	
	public static class TaskTypeDef {
		
		private final @Nullable String persistenceType;
		private final @Nullable String editorType;
		
		public TaskTypeDef(@Nullable final String persistenceType, final @Nullable String editorType) {
			this.persistenceType= persistenceType;
			this.editorType= editorType;
		}
		
		public @Nullable String getType(final WorkingContext context) {
			if (context == Ltk.PERSISTENCE_CONTEXT) {
				return this.persistenceType;
			}
			if (context == Ltk.EDITOR_CONTEXT) {
				return this.editorType;
			}
			return null;
		}
		
	}
	
	
	private final String sourceId;
	
	private final TaskTypeDef taskTypeDef;
	
	private final ImList<ProblemTypeDef> problemTypeDefs;
	
	private final ImIdentitySet<String> persistenceTypes;
	private final ImIdentitySet<String> editorTypes;
	
	
	public IssueTypeSet(final String sourceId,
			final TaskTypeDef taskTypeDef,
			final ImList<ProblemTypeDef> problemTypeDefs) {
		this.sourceId= sourceId;
		this.taskTypeDef= taskTypeDef;
		this.problemTypeDefs= problemTypeDefs;
		
		{	final var list= new ArrayList<String>();
			collectAllTypes(list, Ltk.PERSISTENCE_CONTEXT);
			this.persistenceTypes= ImCollections.toIdentitySet(list);
			list.clear();
			collectAllTypes(list, Ltk.EDITOR_CONTEXT);
			this.editorTypes= ImCollections.toIdentitySet(list);
		}
	}
	
	public IssueTypeSet(final String sourceId, final IssueTypeSet baseSet,
			final @NonNull ProblemTypeDef... addProblemTypeDefs) {
		this(sourceId, baseSet.taskTypeDef, ImCollections.concatList(
				baseSet.problemTypeDefs, ImCollections.newList(addProblemTypeDefs) ));
	}
	
	
	public String getSourceId() {
		return this.sourceId;
	}
	
	public TaskTypeDef getTaskCategory() {
		return this.taskTypeDef;
	}
	
	public ImList<ProblemTypeDef> getProblemCategories() {
		return this.problemTypeDefs;
	}
	
	public @Nullable ProblemTypeDef getProblemCategory(final String categoryId) {
		for (final var problemCategory : this.problemTypeDefs) {
			if (problemCategory.id == categoryId) {
				return problemCategory;
			}
		}
		return null;
	}
	
	
	private void collectAllTypes(final Collection<String> types, final WorkingContext context) {
		{	final String categoryType= getTaskCategory().getType(context);
			if (categoryType != null) {
				types.add(categoryType);
			}
		}
		for (final var category : getProblemCategories()) {
			final ProblemTypes categoryTypes= category.getTypes(context);
			if (categoryTypes != null) {
				types.add(categoryTypes.getType(Problem.SEVERITY_ERROR));
				types.add(categoryTypes.getType(Problem.SEVERITY_WARNING));
				types.add(categoryTypes.getType(Problem.SEVERITY_INFO));
			}
		}
	}
	
	public @Nullable ImIdentitySet<String> getAllTypes(final WorkingContext context) {
		if (context == Ltk.PERSISTENCE_CONTEXT) {
			return this.persistenceTypes;
		}
		if (context == Ltk.EDITOR_CONTEXT) {
			return this.editorTypes;
		}
		return null;
	}
	
}
