package net.minecraft.commands.synchronization;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.arguments.ArgumentType;
import com.mojang.brigadier.tree.ArgumentCommandNode;
import com.mojang.brigadier.tree.CommandNode;
import com.mojang.brigadier.tree.LiteralCommandNode;
import com.mojang.brigadier.tree.RootCommandNode;
import com.mojang.logging.LogUtils;
import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.server.commands.PermissionCheck;
import org.slf4j.Logger;
public class ArgumentUtils {
	private static final Logger LOGGER = LogUtils.getLogger();
	private static final byte NUMBER_FLAG_MIN = 1;
	private static final byte NUMBER_FLAG_MAX = 2;
	public static int createNumberFlags(boolean min, boolean max) {
		int i = 0;
		if (min) {
			i |= 1;
		}
		if (max) {
			i |= 2;
		}
		return i;
	}
	public static boolean numberHasMin(byte number) {
		return (number & 1) != 0;
	}
	public static boolean numberHasMax(byte number) {
		return (number & 2) != 0;
	}
	private static , T extends ArgumentTypeInfo.Template> void serializeArgumentCap(
		JsonObject json, ArgumentTypeInfo type, ArgumentTypeInfo.Template template
	) {
		type.serializeToJson((T)template, json);
	}
	private static > void serializeArgumentToJson(JsonObject json, T type) {
		ArgumentTypeInfo.Template template = ArgumentTypeInfos.unpack(type);
		json.addProperty("type", "argument");
		json.addProperty("parser", String.valueOf(BuiltInRegistries.COMMAND_ARGUMENT_TYPE.getKey(template.type())));
		JsonObject jsonObject = new JsonObject();
		serializeArgumentCap(jsonObject, template.type(), template);
		if (!jsonObject.isEmpty()) {
			json.add("properties", jsonObject);
		}
	}
	public static  JsonObject serializeNodeToJson(CommandDispatcher dispatcher, CommandNode node) {
		JsonObject jsonObject = new JsonObject();
		switch (node) {
			case RootCommandNode rootCommandNode:
				jsonObject.addProperty("type", "root");
				break;
			case LiteralCommandNode literalCommandNode:
				jsonObject.addProperty("type", "literal");
				break;
			case ArgumentCommandNode argumentCommandNode:
				serializeArgumentToJson(jsonObject, argumentCommandNode.getType());
				break;
			default:
				LOGGER.error("Could not serialize node {} ({})!", node, node.getClass());
				jsonObject.addProperty("type", "unknown");
		}
		Collection> collection = node.getChildren();
		if (!collection.isEmpty()) {
			JsonObject jsonObject2 = new JsonObject();
			for (CommandNode commandNode : collection) {
				jsonObject2.add(commandNode.getName(), serializeNodeToJson(dispatcher, commandNode));
			}
			jsonObject.add("children", jsonObject2);
		}
		if (node.getCommand() != null) {
			jsonObject.addProperty("executable", true);
		}
		if (node.getRequirement() instanceof PermissionCheck> permissionCheck) {
			jsonObject.addProperty("required_level", permissionCheck.requiredLevel());
		}
		if (node.getRedirect() != null) {
			Collection collection2 = dispatcher.getPath(node.getRedirect());
			if (!collection2.isEmpty()) {
				JsonArray jsonArray = new JsonArray();
				for (String string : collection2) {
					jsonArray.add(string);
				}
				jsonObject.add("redirect", jsonArray);
			}
		}
		return jsonObject;
	}
	public static  Set> findUsedArgumentTypes(CommandNode node) {
		Set> set = new ReferenceOpenHashSet<>();
		Set> set2 = new HashSet();
		findUsedArgumentTypes(node, set2, set);
		return set2;
	}
	private static  void findUsedArgumentTypes(CommandNode node, Set> types, Set> nodes) {
		if (nodes.add(node)) {
			if (node instanceof ArgumentCommandNode argumentCommandNode) {
				types.add(argumentCommandNode.getType());
			}
			node.getChildren().forEach(commandNodex -> findUsedArgumentTypes(commandNodex, types, nodes));
			CommandNode commandNode = node.getRedirect();
			if (commandNode != null) {
				findUsedArgumentTypes(commandNode, types, nodes);
			}
		}
	}
}