package speiger.src.coreengine.assets.api;

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

import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;

import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.collections.objects.lists.ObjectList;
import speiger.src.collections.objects.utils.ObjectLists;

@NullMarked
public interface IAssetProvider extends AutoCloseable {
	@Nullable
	IAsset get(ID id);	
	@Nullable
	MultiAsset getAll(ID id);
	Map<ID, IAsset> list(String folder, Predicate<ID> filter);
	Map<ID, MultiAsset> listAll(String folder, Predicate<ID> filter);
	
	public static class ReloadTracker {
		ObjectList<Listener> listeners = new ObjectArrayList<>();
		
		public void register(IResourceListener listener) {
			listeners.add(new Listener(listener));
		}
		
		public void register(Predicate<ID> filter, IResourceListener listener) {
			listeners.add(new Listener(filter, listener));
		}
		
		public List<IResourceListener> findByFilter(Set<ID> changed) {
			if(changed.isEmpty()) return ObjectLists.empty();
			List<IResourceListener> result = new ObjectArrayList<>();
			for(int i = 0,m=listeners.size();i<m;i++) {
				Listener listener = listeners.get(i);
				for(ID id : changed) {
					if(listener.contains(id)) {
						result.add(listener.listener());
						break;
					}
				}
			}
			return result;
		}
		
		public List<IResourceListener> listeners() {
			return listeners.map(Listener::listener).pourAsList();
		}
		
		private record Listener(Predicate<ID> filter, IResourceListener listener) {
			public Listener(IResourceListener listener) {
				this(_ -> true, listener);
			}
			
			public boolean contains(ID id) {
				return filter.test(id);
			}
		}
	}
}
