package mezz.jei.util;

import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;

import mezz.jei.Internal;
import mezz.jei.api.recipe.IRecipeHandler;
import mezz.jei.api.recipe.IRecipeWrapper;
import net.minecraft.block.Block;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.ResourceLocation;

public class ErrorUtil {
	public static <T> String getInfoFromBrokenRecipe(T recipe, IRecipeHandler<T> recipeHandler) {
		StringBuilder recipeInfoBuilder = new StringBuilder();
		try {
			recipeInfoBuilder.append(recipe);
		} catch (RuntimeException e) {
			Log.error("Failed recipe.toString", e);
			recipeInfoBuilder.append(recipe.getClass());
		}

		IRecipeWrapper recipeWrapper;

		try {
			recipeWrapper = recipeHandler.getRecipeWrapper(recipe);
		} catch (RuntimeException ignored) {
			recipeInfoBuilder.append("\nFailed to create recipe wrapper");
			return recipeInfoBuilder.toString();
		}

		recipeInfoBuilder.append("\nOutput ItemStacks: ");
		try {
			List outputs = recipeWrapper.getOutputs();
			List<String> itemStackIngredientsInfo = getItemStackIngredientsInfo(outputs);
			recipeInfoBuilder.append(itemStackIngredientsInfo);
		} catch (RuntimeException e) {
			recipeInfoBuilder.append(e.getMessage());
		}

		recipeInfoBuilder.append("\nOutput Fluids: ");
		try {
			recipeInfoBuilder.append(recipeWrapper.getFluidOutputs());
		} catch (RuntimeException e) {
			recipeInfoBuilder.append(e.getMessage());
		}

		recipeInfoBuilder.append("\nInput ItemStacks: ");
		try {
			List inputs = recipeWrapper.getInputs();
			List<String> itemStackIngredientsInfo = getItemStackIngredientsInfo(inputs);
			recipeInfoBuilder.append(itemStackIngredientsInfo);
		} catch (RuntimeException e) {
			recipeInfoBuilder.append(e.getMessage());
		}

		recipeInfoBuilder.append("\nInput Fluids: ");
		try {
			recipeInfoBuilder.append(recipeWrapper.getFluidInputs());
		} catch (RuntimeException e) {
			recipeInfoBuilder.append(e.getMessage());
		}

		return recipeInfoBuilder.toString();
	}

	@Nullable
	public static List<String> getItemStackIngredientsInfo(@Nullable List list) {
		if (list == null) {
			return null;
		}
		StackHelper stackHelper = Internal.getStackHelper();

		List<String> ingredientsInfo = new ArrayList<String>();
		for (Object ingredient : list) {
			List<String> ingredientInfo = new ArrayList<String>();

			List<ItemStack> stacks = stackHelper.toItemStackList(ingredient);
			String oreDict = stackHelper.getOreDictEquivalent(stacks);
			if (oreDict != null) {
				ingredientInfo.add("OreDict: " + oreDict);
			}

			for (ItemStack stack : stacks) {
				String itemStackInfo = getItemStackInfo(stack);
				ingredientInfo.add(itemStackInfo);
			}

			ingredientsInfo.add(ingredientInfo.toString() + "\n");
		}
		return ingredientsInfo;
	}

	public static String getItemStackInfo(@Nullable ItemStack itemStack) {
		if (itemStack == null) {
			return "null";
		}
		Item item = itemStack.getItem();
		if (item == null) {
			return itemStack.stackSize + "x (null)";
		}

		final String itemName;
		ResourceLocation registryName = item.getRegistryName();
		if (registryName != null) {
			itemName = registryName.toString();
		} else if (item instanceof ItemBlock) {
			final String blockName;
			Block block = ((ItemBlock) item).getBlock();
			if (block == null) {
				blockName = "null";
			} else {
				ResourceLocation blockRegistryName = block.getRegistryName();
				if (blockRegistryName != null) {
					blockName = blockRegistryName.toString();
				} else {
					blockName = block.getClass().getName();
				}
			}
			itemName = "ItemBlock(" + blockName + ")";
		} else {
			itemName = item.getClass().getName();
		}

		NBTTagCompound nbt = itemStack.getTagCompound();
		if (nbt != null) {
			return itemStack + " " + itemName + " nbt:" + nbt;
		}
		return itemStack + " " + itemName;
	}
}

@@ -1036,24 +1036,165 @@
 tring();%0A%09%09%7D
+ catch (LinkageError ignored) %7B%0A%09%09%09recipeInfoBuilder.append(%22%5CnFailed to create recipe wrapper%22);%0A%09%09%09return recipeInfoBuilder.toString();%0A%09%09%7D
 %0A%0A%09%09recipeIn

Fix a crash in ErrorUtil from other broken mods (#464)