/*=============================================================================#
 # 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.ui.util;

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

import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.Viewer;

import org.eclipse.statet.jcommons.lang.Disposable;
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.source.SourceModelStamp;
import org.eclipse.statet.ltk.model.core.LtkModelUtils;
import org.eclipse.statet.ltk.model.core.LtkModels;
import org.eclipse.statet.ltk.model.core.element.EmbeddingForeignElement;
import org.eclipse.statet.ltk.model.core.element.LtkModelElement;
import org.eclipse.statet.ltk.model.core.element.LtkModelElementFilter;
import org.eclipse.statet.ltk.model.core.element.SourceStructElement;
import org.eclipse.statet.ltk.model.core.element.SourceUnitModelInfo;
import org.eclipse.statet.ltk.ui.SourceStructContentProvider;


@NonNullByDefault
public class ExtModelContentProvider implements ITreeContentProvider {
	
	
	private static final @NonNull SourceStructElement<?, ?>[] NO_CHILDREN= new SourceStructElement[0];
	
	protected static final SourceStructContentProvider NO_PROVIDER= new SourceStructContentProvider() {
	};
	
	
	private final IdentityHashMap<String, SourceStructContentProvider> providers= new IdentityHashMap<>(4);
	
	
	public interface ModelContent {
		
		@Nullable SourceUnitModelInfo getModelInfo(Object inputElement);
		
		@Nullable LtkModelElementFilter<? super SourceStructElement<?, ?>> getContentFilter();
		
	}
	
	
	private final ModelContent content;
	
	private final ArrayList<SourceStructElement<?, ?>> filteredChildren= new ArrayList<>();
	
	
	public ExtModelContentProvider(final ModelContent content) {
		this.content= content;
	}
	
	@Override
	public void dispose() {
		for (final var provider : this.providers.values()) {
			if (provider instanceof Disposable) {
				((Disposable)provider).dispose();
			}
		}
		this.providers.clear();
	}
	
	
	protected final ModelContent getContent() {
		return this.content;
	}
	
	public @Nullable SourceModelStamp getStamp(final Object inputElement) {
		final SourceUnitModelInfo modelInfo= getContent().getModelInfo(inputElement);
		return (modelInfo != null) ? modelInfo.getStamp() : null;
	}
	
	@Override
	public void inputChanged(final Viewer viewer, final @Nullable Object oldInput, final @Nullable Object newInput) {
	}
	
	
	protected @Nullable SourceStructContentProvider getSourceStructContentProvider(final @Nullable String modelId) {
		if (modelId == null) {
			return null;
		}
		var provider= this.providers.get(modelId);
		if (provider == null) {
			provider= LtkModels.getModelAdapter(modelId, SourceStructContentProvider.class);
			if (provider == null) {
				provider= NO_PROVIDER;
			}
			this.providers.put(modelId, provider);
		}
		return (provider != NO_PROVIDER) ? provider : null;
	}
	
	protected void addProvider(final String modelId, final SourceStructContentProvider provider) {
		this.providers.put(modelId, provider);
	}
	
	
	private @NonNull SourceStructElement<?, ?>[] filter(
			final List<? extends SourceStructElement<?, ?>> elements,
			final @Nullable LtkModelElementFilter<? super SourceStructElement<?, ?>> filter) {
		if (elements.isEmpty()) {
			return NO_CHILDREN;
		}
		if (filter == null) {
			return elements.toArray(new @NonNull SourceStructElement[elements.size()]);
		}
		try {
			for (final var element : elements) {
				if (filter.include(element)) {
					this.filteredChildren.add(element);
				}
			}
			return this.filteredChildren.toArray(new @NonNull SourceStructElement[elements.size()]);
		}
		finally {
			this.filteredChildren.clear();
		}
	}
	
	
	private boolean skipToForeignElement(final @Nullable SourceStructElement<?, ?> element) {
		return (element != null
				&& (element.getElementType() & LtkModelElement.MASK_C1) == LtkModelElement.C1_EMBEDDED );
	}
	
	protected boolean skipInTree(final SourceStructElement<?, ?> element) {
		return false;
	}
	
	protected @NonNull SourceStructElement<?, ?>[] getElements(final @Nullable SourceUnitModelInfo modelInfo) {
		if (modelInfo != null) {
			final var children= modelInfo.getSourceElement()
					.getSourceChildren(getContent().getContentFilter());
			return children.toArray(new @NonNull SourceStructElement[children.size()]);
		}
		return NO_CHILDREN;
	}
	
	protected @Nullable SourceStructElement<?, ?> getParent(final SourceStructElement<?, ?> element) {
		var parent= element.getSourceParent();
		while (parent != null && (skipToForeignElement(parent) || skipInTree(parent))) {
			parent= parent.getSourceParent();
		}
		return parent;
	}
	
	protected boolean hasChildren(@Nullable SourceStructElement<?, ?> element) {
		if (skipToForeignElement(element)) {
			element= ((EmbeddingForeignElement<?, ?>)element).getForeignElement();
		}
		SourceStructContentProvider provider;
		if (element != null) {
			if ((provider= getSourceStructContentProvider(element.getModelTypeId())) != null) {
				return provider.hasSourceChildren(element, getContent().getContentFilter());
			}
			else {
				return element.hasSourceChildren(getContent().getContentFilter());
			}
		}
		return false;
	}
	
	protected @NonNull SourceStructElement<?, ?>[] getChildren(@Nullable SourceStructElement<?, ?> element) {
		if (skipToForeignElement(element)) {
			element= ((EmbeddingForeignElement<?, ?>)element).getForeignElement();
		}
		SourceStructContentProvider provider;
		if (element != null) {
			try {
				if ((provider= getSourceStructContentProvider(element.getModelTypeId())) != null) {
					final var children= provider.getSourceChildren(element,
							getContent().getContentFilter(), this.filteredChildren );
					return children.toArray(new @NonNull SourceStructElement[children.size()]);
				}
				else {
					final var children= LtkModelUtils.filter(element.getSourceChildren(null),
							getContent().getContentFilter(), this.filteredChildren );
					return children.toArray(new @NonNull SourceStructElement[children.size()]);
				}
			}
			finally {
				this.filteredChildren.clear();
			}
		}
		return NO_CHILDREN;
	}
	
	
	@Override
	public @NonNull Object[] getElements(final Object inputElement) {
		return getElements(getContent().getModelInfo(inputElement));
	}
	
	@Override
	public @Nullable Object getParent(final Object element) {
		if (element instanceof SourceStructElement) {
			return getParent((SourceStructElement<?, ?>)element);
		}
		return null;
	}
	
	@Override
	public boolean hasChildren(final Object element) {
		if (element instanceof SourceStructElement) {
			return hasChildren((SourceStructElement<?, ?>)element);
		}
		return false;
	}
	
	@Override
	public @NonNull Object[] getChildren(final Object element) {
		if (element instanceof SourceStructElement) {
			return getChildren((SourceStructElement<?, ?>)element);
		}
		return NO_CHILDREN;
	}

}
