package protocolsupport.zplatform.impl.glowstone;

import java.security.KeyPair;
import java.text.MessageFormat;
import java.util.Arrays;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import java.util.stream.Collectors;

import org.bukkit.Achievement;
import org.bukkit.Bukkit;
import org.bukkit.Statistic;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.CachedServerIcon;

import io.netty.channel.Channel;
import io.netty.channel.ChannelPipeline;
import net.glowstone.GlowServer;
import net.glowstone.constants.GlowAchievement;
import net.glowstone.constants.GlowStatistic;
import net.glowstone.entity.meta.profile.PlayerProfile;
import net.glowstone.entity.meta.profile.PlayerProperty;
import net.glowstone.io.nbt.NbtSerialization;
import net.glowstone.net.protocol.ProtocolType;
import net.glowstone.util.GlowServerIcon;
import protocolsupport.protocol.pipeline.IPacketPrepender;
import protocolsupport.protocol.pipeline.IPacketSplitter;
import protocolsupport.protocol.utils.authlib.GameProfile;
import protocolsupport.zplatform.PlatformUtils;
import protocolsupport.zplatform.impl.glowstone.itemstack.GlowStoneNBTTagCompoundWrapper;
import protocolsupport.zplatform.impl.glowstone.network.GlowStoneChannelHandlers;
import protocolsupport.zplatform.impl.glowstone.network.GlowStoneNetworkManagerWrapper;
import protocolsupport.zplatform.impl.glowstone.network.pipeline.GlowStoneFramingHandler;
import protocolsupport.zplatform.itemstack.NBTTagCompoundWrapper;
import protocolsupport.zplatform.network.NetworkManagerWrapper;
import protocolsupport.zplatform.network.NetworkState;

public class GlowStoneMiscUtils implements PlatformUtils {

	public static GlowServer getServer() {
		return ((GlowServer) Bukkit.getServer());
	}

	public static PlayerProfile toGlowStoneGameProfile(GameProfile profile) {
		return new PlayerProfile(
			profile.getName(), profile.getUUID(),
			profile.getProperties().values()
			.stream()
			.map(property -> new PlayerProperty(property.getName(), property.getValue(), property.getSignature()))
			.collect(Collectors.toList())
		);
	}

	public static ProtocolType netStateToProtocol(NetworkState type) {
		switch (type) {
			case HANDSHAKING: {
				return ProtocolType.HANDSHAKE;
			}
			case PLAY: {
				return ProtocolType.PLAY;
			}
			case LOGIN: {
				return ProtocolType.LOGIN;
			}
			case STATUS: {
				return ProtocolType.STATUS;
			}
			default: {
				throw new IllegalArgumentException(MessageFormat.format("Unknown state {0}", type));
			}
		}
	}

	public static NetworkState protocolToNetState(ProtocolType type) {
		switch (type) {
			case HANDSHAKE: {
				return NetworkState.HANDSHAKING;
			}
			case LOGIN: {
				return NetworkState.LOGIN;
			}
			case STATUS: {
				return NetworkState.STATUS;
			}
			case PLAY: {
				return NetworkState.PLAY;
			}
			default: {
				throw new IllegalArgumentException(MessageFormat.format("Unknown protocol {0}", type));
			}
		}
	}

	@Override
	public String localize(String key, Object... args) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public ItemStack createItemStackFromNBTTag(NBTTagCompoundWrapper tag) {
		return NbtSerialization.readItem(((GlowStoneNBTTagCompoundWrapper) tag).unwrap());
	}

	@Override
	public NBTTagCompoundWrapper createNBTTagFromItemStack(ItemStack itemstack) {
		return GlowStoneNBTTagCompoundWrapper.wrap(NbtSerialization.writeItem(itemstack, 0));
	}

	@Override
	public String getOutdatedServerMessage() {
		return "Outdated server! I\'m running {0}";
	}

	@Override
	public boolean isBungeeEnabled() {
		return getServer().getProxySupport();
	}

	@Override
	public boolean isDebugging() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public void enableDebug() {
		// TODO Auto-generated method stub

	}

	@Override
	public void disableDebug() {
		// TODO Auto-generated method stub

	}

	@Override
	public int getCompressionThreshold() {
		return getServer().getCompressionThreshold();
	}

	@Override
	public KeyPair getEncryptionKeyPair() {
		return getServer().getKeyPair();
	}

	@Override
	public <V> FutureTask<V> callSyncTask(Callable<V> call) {
		FutureTask<V> task = new FutureTask<>(call);
		Bukkit.getScheduler().scheduleSyncDelayedTask(null, task);
		return task;
	}

	@Override
	public String getModName() {
		return "GlowStone";
	}

	@Override
	public String getVersionName() {
		return GlowServer.GAME_VERSION;
	}

	private static final Map<String, Statistic> statByName = Arrays.stream(Statistic.values())
	.collect(Collectors.toMap(stat -> GlowStatistic.getName(stat), stat -> stat));
	private static final Map<String, Achievement> achByName = Arrays.stream(Achievement.values())
	.collect(Collectors.toMap(ach -> GlowAchievement.getName(ach), ach -> ach));

	@Override
	public Statistic getStatisticByName(String value) {
		return statByName.get(value);
	}

	@Override
	public String getStatisticName(Statistic stat) {
		return GlowStatistic.getName(stat);
	}

	@Override
	public Achievement getAchievmentByName(String value) {
		return achByName.get(value);
	}

	@Override
	public String getAchievmentName(Achievement achievement) {
		return GlowAchievement.getName(achievement);
	}

	@Override
	public String convertBukkitIconToBase64(CachedServerIcon icon) {
		return ((GlowServerIcon) icon).getData();
	}

	@Override
	public NetworkState getNetworkStateFromChannel(Channel channel) {
		return GlowStoneNetworkManagerWrapper.getFromChannel(channel).getProtocol();
	}

	@Override
	public NetworkManagerWrapper getNetworkManagerFromChannel(Channel channel) {
		return GlowStoneNetworkManagerWrapper.getFromChannel(channel);
	}

	@Override
	public String getReadTimeoutHandlerName() {
		return GlowStoneChannelHandlers.READ_TIMEOUT;
	}

	@Override
	public String getSplitterHandlerName() {
		return GlowStoneChannelHandlers.FRAMING;
	}

	@Override
	public String getPrependerHandlerName() {
		return GlowStoneChannelHandlers.FRAMING;
	}

	@Override
	public void setFraming(ChannelPipeline pipeline, IPacketSplitter splitter, IPacketPrepender prepender) {
		((GlowStoneFramingHandler) pipeline.get(GlowStoneChannelHandlers.FRAMING)).setRealFraming(prepender, splitter);
	}

}

@@ -3649,32 +3649,65 @@
 ySupport();%0A%09%7D%0A%0A
+%09private boolean debug = false;%0A%0A
 %09@Override%0A%09publ
@@ -3739,56 +3739,27 @@
 %7B%0A%09%09
-// TODO Auto-generated method stub%0A%09%09return fals
+return debug == tru
 e;%0A%09
@@ -3807,43 +3807,21 @@
 %7B%0A%09%09
-// TODO Auto-generated method stub%0A
+debug = true;
 %0A%09%7D%0A
@@ -3868,43 +3868,22 @@
 %7B%0A%09%09
-// TODO Auto-generated method stub%0A
+debug = false;
 %0A%09%7D%0A

Debug for glowstone