package thb.jeanluc.adventure.command;

import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Optional;
import java.util.Set;

/**
 * Verb-to-{@link Command} dispatch table. Backed by a {@link HashMap}
 * (O(1) lookup), with each command optionally registered under multiple
 * aliases.
 */
public class CommandRegistry {

    /** Lookup table; multiple aliases may map to the same command instance. */
    private final Map<String, Command> commands = new HashMap<>();

    /**
     * Registers a command under one or more verbs (aliases). All names
     * are stored lowercase to keep dispatch case-insensitive.
     *
     * @param cmd   the command to register
     * @param names one or more verb aliases
     */
    public void register(Command cmd, String... names) {
        for (String n : names) {
            commands.put(n.toLowerCase(), cmd);
        }
    }

    /**
     * Looks up a command by verb.
     *
     * @param verb verb token, case-insensitive
     * @return the matching command, or empty if no command is registered
     */
    public Optional<Command> find(String verb) {
        if (verb == null) {
            return Optional.empty();
        }
        return Optional.ofNullable(commands.get(verb.toLowerCase()));
    }

    /**
     * Returns the set of distinct command instances (deduplicated across
     * aliases). Used by {@code HelpCommand} to list help texts.
     *
     * @return distinct commands in insertion order
     */
    public Set<Command> distinctCommands() {
        return new LinkedHashSet<>(commands.values());
    }
}
