/*=============================================================================#
 # Copyright (c) 2012, 2018 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.rj.renv.core;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.eclipse.statet.jcommons.collections.SortedArraySet;
import org.eclipse.statet.jcommons.lang.NonNull;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;


@NonNullByDefault
public class BasicRPkgCompilation<T extends RPkg> implements RPkgCompilation<T> {
	
	
	/** Package sources */
	private final List<String> sources;
	/** Packages by sources */
	private final List<RPkgList<T>> pkgLists;
	
	private @Nullable volatile List<String> names;
	
	
	public BasicRPkgCompilation(final int size) {
		this.sources= new ArrayList<>(size);
		this.pkgLists= new ArrayList<>(size);
	}
	
	
	public void add(final String source, final RPkgList<T> list) {
		this.sources.add((source != null) ? source : ""); //$NON-NLS-1$
		this.pkgLists.add(list);
	}
	
	public RPkgList<T> getOrAdd(final String source) {
		RPkgList<T> list= getBySource(source);
		if (list == null) {
			list= newPkgList();
			add(source, list);
		}
		return list;
	}
	
	protected RPkgList<T> newPkgList() {
		return new BasicRPkgList<>(4);
	}
	
	
	@Override
	@SuppressWarnings("null")
	public List<String> getNames() {
		if (this.names == null) {
			createNames();
		}
		return this.names;
	}
	
	private synchronized void createNames() {
		if (this.names != null) {
			return;
		}
		if (this.pkgLists.isEmpty()) {
			this.names= Collections.emptyList();
			return;
		}
		{	final SortedArraySet<String> names= new SortedArraySet<>(
					new @NonNull String[Math.min(16, this.pkgLists.get(0).size())], 0,
					RPkgUtils.NAMES_COLLATOR );
			for (final RPkgList<? extends RPkg> list : this.pkgLists) {
				for (int i= 0; i < list.size(); i++) {
					names.addE(list.get(i).getName());
				}
			}
			this.names= Collections.unmodifiableList(names);
		}
	}
	
	@Override
	public boolean contains(final String name) {
		for (final RPkgList<? extends RPkg> list : this.pkgLists) {
			final int idx= list.indexOf(name);
			if (idx >= 0) {
				return true;
			}
		}
		return false;
	}
	
	@Override
	public @Nullable T getFirst(final String name) {
		for (final RPkgList<T> list : this.pkgLists) {
			final int idx= list.indexOf(name);
			if (idx >= 0) {
				return list.get(idx);
			}
		}
		return null;
	}
	
	@Override
	public List<T> get(final String name) {
		List<T> result= null;
		for (final RPkgList<T> list : this.pkgLists) {
			final int idx= list.indexOf(name);
			if (idx >= 0) {
				if (result == null) {
					result= new ArrayList<>(2);
				}
				result.add(list.get(idx));
			}
		}
		return (result != null) ? result : Collections.<T>emptyList();
	}
	
	@Override
	public List<String> getSources() {
		return this.sources;
	}
	
	@Override
	public @Nullable RPkgList<T> getBySource(final String source) {
		final int idx= this.sources.indexOf(source);
		return (idx >= 0) ? this.pkgLists.get(idx) : null;
	}
	
	@Override
	public List<RPkgList<T>> getAll() {
		return this.pkgLists;
	}
	
}
