package me.nallar.tickthreading.minecraft.commands;

import java.lang.reflect.Field;
import java.util.List;

import me.nallar.tickthreading.Log;
import me.nallar.tickthreading.minecraft.TickThreading;
import me.nallar.tickthreading.util.TableFormatter;
import net.minecraft.command.ICommandSender;
import net.minecraft.entity.Entity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import net.minecraftforge.common.DimensionManager;

public class DumpCommand extends Command {
	public static String name = "dump";

	@Override
	public String getCommandName() {
		return name;
	}

	@Override
	public boolean canCommandSenderUseCommand(ICommandSender commandSender) {
		return !TickThreading.instance.requireOpForDumpCommand || super.canCommandSenderUseCommand(commandSender);
	}

	@Override
	public void processCommand(final ICommandSender commandSender, List<String> arguments) {
		World world = DimensionManager.getWorld(0);
		int x = 0;
		int y = 0;
		int z = 0;
		try {
			if (commandSender instanceof Entity) {
				world = ((Entity) commandSender).worldObj;
			}
			x = Integer.parseInt(arguments.remove(0));
			y = Integer.parseInt(arguments.remove(0));
			z = Integer.parseInt(arguments.remove(0));
			if (!arguments.isEmpty()) {
				world = DimensionManager.getWorld(Integer.parseInt(arguments.remove(0)));
			}
		} catch (Exception e) {
			world = null;
		}
		if (world == null) {
			sendChat(commandSender, "Usage: /dump x y z [world=currentworld]");
		}
		sendChat(commandSender, dump(new TableFormatter(commandSender), world, x, y, z).toString());
	}

	public static TableFormatter dump(TableFormatter tf, World world, int x, int y, int z) {
		StringBuilder sb = tf.sb;
		int blockId = world.getBlockIdWithoutLoad(x, y, z);
		if (blockId < 1) {
			sb.append("No loaded block at ").append(Log.name(world)).append("x,y,z").append(x).append(',').append(y).append(',').append(z);
		}
		TileEntity toDump = world.getTEWithoutLoad(x, y, z);
		if (toDump == null) {
			sb.append("No tile entity at ").append(Log.name(world)).append("x,y,z").append(x).append(',').append(y).append(',').append(z);
			return tf;
		}
		tf
				.heading("Field")
				.heading("Value");
		Class<?> clazz = toDump.getClass();
		do {
			for (Field field : clazz.getDeclaredFields()) {
				field.setAccessible(true);
				tf.row(field.getName());
				try {
					String value = String.valueOf(field.get(toDump));
					tf.row(value.substring(0, Math.min(value.length(), 32)));
				} catch (IllegalAccessException e) {
					tf.row(e.getMessage());
				}
			}
		} while ((clazz = clazz.getSuperclass()) != Object.class);
		tf.finishTable();
		return tf;
	}
}

@@ -103,24 +103,52 @@
 il.List;%0D%0A%0D%0A
+import javassist.Modifier;%0D%0A
 import me.na
@@ -278,24 +278,59 @@
 Formatter;%0D%0A
+import net.minecraft.block.Block;%0D%0A
 import net.m
@@ -392,32 +392,103 @@
 entity.Entity;%0D%0A
+import net.minecraft.item.Item;%0D%0Aimport net.minecraft.item.ItemStack;%0D%0A
 import net.minec
@@ -1749,16 +1749,59 @@
  x, y, z
+, commandSender instanceof Entity ? 35 : 70
 ).toStri
@@ -1900,16 +1900,28 @@
 y, int z
+, int maxLen
 ) %7B%0D%0A%09%09S
@@ -2044,15 +2044,8 @@
 %22No 
-loaded 
 bloc
@@ -2076,32 +2076,33 @@
 world)).append(%22
+ 
 x,y,z%22).append(x
@@ -2142,24 +2142,507 @@
 ').append(z)
+.append('%5Cn');%0D%0A%09%09%7D else %7B%0D%0A%09%09%09int metaData = world.getBlockMetadata(x, y, z);%0D%0A%09%09%09Block type = Block.blocksList%5BblockId%5D;%0D%0A%09%09%09Item item = type == null ? null : Item.itemsList%5BblockId%5D;%0D%0A%09%09%09ItemStack itemType = item == null ? null : new ItemStack(blockId, 1, metaData);%0D%0A%09%09%09String name = itemType == null ? (type == null ? %22unknown%22 : type.translateBlockName()) : item.getItemNameIS(itemType);%0D%0A%09%09%09sb.append(blockId).append(':').append(name).append(':').append(metaData).append('%5Cn')
 ;%0D%0A%09%09%7D%0D%0A%09%09Ti
@@ -2785,16 +2785,17 @@
 append(%22
+ 
 x,y,z%22).
@@ -2847,16 +2847,29 @@
 ppend(z)
+.append('%5Cn')
 ;%0D%0A%09%09%09re
@@ -3031,24 +3031,119 @@
 ields()) %7B%0D%0A
+%09%09%09%09if ((field.getModifiers() & Modifier.STATIC) == Modifier.STATIC) %7B%0D%0A%09%09%09%09%09continue;%0D%0A%09%09%09%09%7D%0D%0A
 %09%09%09%09field.se
@@ -3319,10 +3319,14 @@
 (), 
-32
+maxLen
 )));

Improve /dump - don't show static fields, give correct block name.