package leigh.minecraft.link.cmd;

import leigh.eo.EO;
import leigh.eo.EOLoop;
import leigh.mecha.log.MechaLogger;
import leigh.mecha.log.MechaLoggerFactory;
import leigh.minecraft.link.MinecraftLinkConstants;
import org.bukkit.Location;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;

import java.util.Arrays;
import java.util.Objects;

/**
 * This class holds Bukkit-specific information about a client command invocation.
 *
 * @author Alex Leigh
 */
public class PlayerCommand {
    private static final MechaLogger logger = MechaLoggerFactory.getLogger(PlayerCommand.class);
    private final CommandSender sender;
    private final Command command;
    private final String[] args;

    public PlayerCommand(CommandSender sender, Command command, String[] args) {
        this.sender = sender;
        this.command = command;
        this.args = args;
    }

    /**
     * Return the sender for the command.
     */
    public CommandSender getSender() {
        return sender;
    }

    /**
     * Return the command.
     */
    public Command getCommand() {
        return command;
    }

    public String[] getArgs() {
        return args;
    }

    /**
     * Return the command data in EO format. This is suitable for sending out on the wire.
     */
    public EO makeEo() {
        EO cmd = new EO("leigh.minecraft.link.Command");
        cmd.setValue(MinecraftLinkConstants.SRC_KEY, sender.getName());

        Player player = sender.getServer().getPlayer(sender.getName());
        Location loc = player.getLocation();

        cmd.setValue(MinecraftLinkConstants.ARG_POS_X, loc.getBlockX());
        cmd.setValue(MinecraftLinkConstants.ARG_POS_Y, loc.getBlockY());
        cmd.setValue(MinecraftLinkConstants.ARG_POS_Z, loc.getBlockZ());
        cmd.setValue(MinecraftLinkConstants.ARG_POS_PITCH, loc.getPitch());
        cmd.setValue(MinecraftLinkConstants.ARG_POS_YAW, loc.getYaw());
        cmd.setValue("playerId", player.getUniqueId());

        EOLoop argsLoop = cmd.getValueLoop(MinecraftLinkConstants.ARGS_KEY);
        argsLoop.add(new EO().setValue("arg", command.getName()));
        for (String arg : this.args) {
            argsLoop.add(new EO().setValue("arg", arg));
        }

        return cmd;
    }

    @Override
    public String toString() {
        return "PlayerCommand{" +
                "sender=" + sender +
                ", command=" + command +
                ", args=" + Arrays.toString(args) +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        PlayerCommand that = (PlayerCommand) o;
        return Objects.equals(sender, that.sender) && Objects.equals(command, that.command)
                && Arrays.equals(args, that.args);
    }

    @Override
    public int hashCode() {
        int result = Objects.hash(sender, command);
        result = 31 * result + Arrays.hashCode(args);
        return result;
    }
}
