package speiger.src.coreengine.assets.providers;

import java.util.List;
import java.util.Map;
import java.util.function.Predicate;

import org.jspecify.annotations.Nullable;

import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.collections.objects.lists.ObjectList;
import speiger.src.collections.objects.maps.interfaces.Object2ObjectMap;
import speiger.src.collections.objects.utils.ObjectLists;
import speiger.src.collections.objects.utils.maps.Object2ObjectMaps;
import speiger.src.coreengine.assets.api.IAsset;
import speiger.src.coreengine.assets.api.IAssetPackage;
import speiger.src.coreengine.assets.api.ID;
import speiger.src.coreengine.assets.api.MultiAsset;

public class SingleProvider implements BaseProvider {
	IAssetPackage pack;
	List<String> domains;
	
	public SingleProvider(IAssetPackage pack) {
		this.pack = pack;
		this.domains = pack.domains();
	}
	
	@Override
	public void close() throws Exception {
		pack.close();
	}
	
	@Override
	public List<IAssetPackage> packages() {
		return ObjectLists.singleton(pack);
	}
	
	@Override
	public @Nullable IAsset get(ID id) {
		return pack.get(id);
	}
	
	@Override
	public @Nullable MultiAsset getAll(ID id) {
		IAsset asset = pack.get(id);
		return asset == null ? null : new MultiAsset(asset);
	}
	
	@Override
	public Map<ID, IAsset> list(String folder, Predicate<ID> filter) {
		Map<ID, IAsset> result = Object2ObjectMap.builder().linkedMap();
		for(String domain : domains) {
			pack.getAll(ID.of(domain, folder), (K, V) -> {
				if(filter.test(K)) result.putIfAbsent(K, V);
			});
		}
		return result;
	}
	
	@Override
	public Map<ID, MultiAsset> listAll(String folder, Predicate<ID> filter) {
		Object2ObjectMap<ID, ObjectList<IAsset>> assets = Object2ObjectMap.builder().linkedMap();
		for(String domain : domains) {
			pack.getAll(ID.of(domain, folder), (K, V) -> {
				if(filter.test(K)) assets.supplyIfAbsent(K, ObjectArrayList::new).add(V);
			});
		}
		Map<ID, MultiAsset> result = Object2ObjectMap.builder().linkedMap();
		for(Object2ObjectMap.Entry<ID, ObjectList<IAsset>> entry : Object2ObjectMaps.fastIterable(assets)) {
			result.put(entry.getKey(), new MultiAsset(entry.getValue()));
		}
		return result;
	}
}