package speiger.src.coreengine.assets.impl;

import java.io.File;
import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collection;
import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Stream;

import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.coreengine.assets.AssetLocation;
import speiger.src.coreengine.assets.IAsset;
import speiger.src.coreengine.assets.IAssetPackage;
import speiger.src.coreengine.assets.IAssetParser;
import speiger.src.coreengine.utils.collections.iterators.IterableWrapper;

public class FolderAssetPackage implements IAssetPackage
{
	Path baseFolder;
	Function<Class<?>, IAssetParser<?>> parsers;
	
	public FolderAssetPackage(File baseFolder)
	{
		this(baseFolder.toPath());
	}
	
	public FolderAssetPackage(Path baseFolder)
	{
		this.baseFolder = baseFolder;
	}
	
	@Override
	public void setParsers(Function<Class<?>, IAssetParser<?>> parsers)
	{
		this.parsers = parsers;
	}
	
	@Override
	public List<String> getDomains()
	{
		List<String> domains = new ObjectArrayList<>();
		try(DirectoryStream<Path> dirs = Files.newDirectoryStream(baseFolder.resolve("assets")))
		{
			for(Path path : dirs)
			{
				domains.add(path.getFileName().toString());
			}
		}
		catch(IOException e)
		{
			e.printStackTrace();
		}
		return domains;
	}
	
	@Override
	public IAsset getAsset(AssetLocation location)
	{
		Path path = baseFolder.resolve(location.getActualLocation());
		return Files.exists(path) ? new FolderAsset(location, path, parsers) : null;
	}
	
	@Override
	public void getAllAssets(AssetLocation folder, Predicate<String> fileNames, int maxDepth, Collection<AssetLocation> result)
	{
		Path start = baseFolder.resolve(folder.getActualLocation());
		if(Files.notExists(start)) return;
		try(Stream<Path> stream = Files.walk(start, maxDepth).filter(Files::isRegularFile).filter(T -> fileNames.test(T.getFileName().toString())))
		{
			for(Path path : IterableWrapper.wrap(stream.iterator()))
			{
				result.add(folder.subAsset(start.relativize(path).toString().replace("\\", "/")));
			}
		}
		catch(IOException e)
		{
			e.printStackTrace();
		}
	}
}