package speiger.src.coreengine.assets.impl;

import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.function.Function;

import javax.imageio.ImageIO;

import com.google.gson.JsonObject;

import speiger.src.coreengine.assets.AssetLocation;
import speiger.src.coreengine.assets.IAsset;
import speiger.src.coreengine.assets.IAssetParser;
import speiger.src.coreengine.utils.helpers.JsonUtil;

public class ZipAsset implements IAsset
{
	Runnable closer;
	AssetLocation location;
	Path path;
	Function<Class<?>, IAssetParser<?>> parsers;

	public ZipAsset(Runnable closer, AssetLocation location, Path path, Function<Class<?>, IAssetParser<?>> parsers)
	{
		this.closer = closer;
		this.location = location;
		this.path = path;
		this.parsers = parsers;
	}

	@Override
	public void close() throws IOException
	{
		if(closer != null)
		{
			closer.run();
			closer = null;
		}
	}
	
	private void closeInternal()
	{
		if(closer != null)
		{
			closer.run();
			closer = null;
		}
	}
	
	@Override
	public IAsset subAsset(String alternative)
	{
		if(closer == null) return null;
		Path newPath = path.resolveSibling(path.getFileName().toString()+"."+alternative);
		return Files.exists(newPath) ? new ZipAsset(this::closeInternal, location.alternate(alternative), newPath, parsers) : null;
	}
	
	@Override
	public AssetLocation getLocation()
	{
		return location;
	}
	
	@Override
	public InputStream getStream() throws IOException
	{
		return Files.newInputStream(path);
	}
	
	@Override
	public ByteBuffer getBytes() throws IOException
	{
		return ByteBuffer.wrap(Files.readAllBytes(path));
	}
	
	@Override
	public BufferedImage getTexture() throws Exception
	{
		return ImageIO.read(getStream());
	}
	
	@Override
	public BufferedReader getStringReader() throws IOException
	{
		return Files.newBufferedReader(path);
	}
	
	@Override
	public JsonObject getJsonObject() throws IOException
	{
		return JsonUtil.loadFile(path);
	}
	
	@Override
	public <T> T getCustom(Class<T> clz) throws IOException
	{
		return clz.cast(parsers.apply(clz).parseAsset(path, T -> {}));
	}
}