
package org.spongepowered.common.command.registrar.tree.builder;

import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.tree.CommandNode;
import com.mojang.brigadier.tree.LiteralCommandNode;
import com.mojang.brigadier.tree.RootCommandNode;
import net.minecraft.commands.SharedSuggestionProvider;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.spongepowered.api.command.CommandCause;
import org.spongepowered.api.command.registrar.tree.CommandTreeNode;
import org.spongepowered.common.command.brigadier.tree.ForcedRedirectNode;

import java.util.IdentityHashMap;
import java.util.LinkedHashMap;
import java.util.Map;

public final class RootCommandTreeNode extends AbstractCommandTreeNode<CommandTreeNode.Root, RootCommandNode<SharedSuggestionProvider>>
        implements CommandTreeNode.Root {

    public @Nullable CommandNode<SharedSuggestionProvider> createArgumentTree(final CommandCause cause, final LiteralArgumentBuilder<SharedSuggestionProvider> rootBuilder) {
        if (this.getRequirement().test(cause)) {
            final Map<AbstractCommandTreeNode<?, ?>, CommandNode<SharedSuggestionProvider>> nodeToSuggestionProvider = new IdentityHashMap<>();
            // this is going to be iterated only.
            final Map<ForcedRedirectNode, AbstractCommandTreeNode<?, ?>> redirectsToApply = new LinkedHashMap<>();

            if (this.isExecutable()) {
                rootBuilder.executes(c -> 1);
            }

            final LiteralCommandNode<SharedSuggestionProvider> rootNode = rootBuilder.build();
            this.addChildNodesToTree(
                    cause,
                    rootNode,
                    nodeToSuggestionProvider,
                    redirectsToApply
            );

            // now create the redirects.
            redirectsToApply.forEach((node, key) -> node.setForcedRedirect(nodeToSuggestionProvider.get(key)));
            return rootNode;
        }
        return null;
    }

    @Override
    protected RootCommandNode<SharedSuggestionProvider> createElement(final String nodeKey) {
        // node key is ignored.
        return new RootCommandNode<>();
    }
}
