package com.techcavern.wavetact.ircCommands.minecraft;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.techcavern.wavetact.annot.IRCCMD;
import com.techcavern.wavetact.objects.IRCCommand;
import com.techcavern.wavetact.utils.DatabaseUtils;
import com.techcavern.wavetact.utils.GeneralUtils;
import com.techcavern.wavetact.utils.IRCUtils;
import com.techcavern.wavetactdb.tables.Channelproperty;
import org.apache.commons.lang3.StringUtils;
import org.jooq.*;
import org.pircbotx.Channel;
import org.pircbotx.PircBotX;
import org.pircbotx.User;
import org.xbill.DNS.*;
import org.xbill.DNS.Record;

import java.io.*;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@IRCCMD
public class MCServerInfo extends IRCCommand {

    public MCServerInfo() {
        super(GeneralUtils.toArray("mcserverinfo mcsi mcserver mcping mclist mcwho mcplayers"), 5, "mcserverinfo [address] (port)", "Gets info on minecraft server", false);
    }

    @Override
    public void onCommand(String command, User user, PircBotX network, String prefix, Channel channel, boolean isPrivate, int userPermLevel, String... args) throws Exception {
        int port = 25565;
        if(args.length < 1){
            org.jooq.Record rec = DatabaseUtils.getChannelProperty(IRCUtils.getNetworkNameByNetwork(network),channel.getName(), "mcserver");
            if (rec != null){
                args = StringUtils.split(rec.getValue(Channelproperty.CHANNELPROPERTY.VALUE),":");
            }else{
                IRCUtils.sendError(user, network, channel, "Default Minecraft Server Undefined", prefix);
                return;
            }
        }
        if (args.length >= 2) {
            port = Integer.parseInt(args[1]);
        }
        InetSocketAddress address = new InetSocketAddress(GeneralUtils.getIP(args[0], network, false), port);
        Socket socket = new Socket();
        socket.connect(address, 10000);
        OutputStream preout = socket.getOutputStream();
        DataOutputStream out = new DataOutputStream(preout);
        InputStream prein = socket.getInputStream();
        InputStreamReader inreader = new InputStreamReader(prein);
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        DataOutputStream handshake = new DataOutputStream(bos);
        handshake.writeByte(0x00);
        GeneralUtils.writeOutputStream(handshake, 4);
        GeneralUtils.writeOutputStream(handshake, address.getHostString().length());
        handshake.writeBytes(address.getHostString());
        handshake.writeShort(address.getPort());
        GeneralUtils.writeOutputStream(handshake, 1);
        GeneralUtils.writeOutputStream(out, bos.size());
        out.write(bos.toByteArray());
        out.writeByte(0x01);
        out.writeByte(0x00);
        DataInputStream in = new DataInputStream(prein);
        int size =  GeneralUtils.readInputStream(in);
        int id = GeneralUtils.readInputStream(in);
        if (id != 0x00) {
            IRCUtils.sendError(user, network, channel, "Error parsing packet response", prefix);
            return;
        }
        int length = GeneralUtils.readInputStream(in);
        if (length == 0 || length == -1) {
            IRCUtils.sendError(user, network, channel, "Error parsing packet response", prefix);
            return;
        }
        byte[] bits = new byte[length];
        in.readFully(bits);
        String json = new String(bits);
        long now = System.currentTimeMillis();
        out.writeByte(0x09); //size of packet
        out.writeByte(0x01); //0x01 for ping
        out.writeLong(now); //time!?
        size =  GeneralUtils.readInputStream(in);
        id = GeneralUtils.readInputStream(in);
        if (id != 0x01) {
            IRCUtils.sendError(user, network, channel, "Error parsing packet response", prefix);
            return;
        }
        long pingtime = in.readLong(); //read response
        JsonObject response = new JsonParser().parse(json).getAsJsonObject();
        out.close();
        preout.close();
        inreader.close();
        prein.close();
        socket.close();

        String gameVersion = "VERSION: " + response.get("version").getAsJsonObject().get("name").getAsString();
        String motd;
        try {
            motd = "MOTD: " + response.get("description").getAsJsonObject().get("text").getAsString();
        }catch(IllegalStateException e){
            motd = "MOTD: " + response.get("description").getAsString();
        }
        String playercount = "Players: " + response.get("players").getAsJsonObject().get("online").getAsString() + "/" + response.get("players").getAsJsonObject().get("max").getAsString();
        List<String> players = new ArrayList<>();
        if(response.get("players").getAsJsonObject().get("online").getAsInt() > 0){
            for(JsonElement e:response.get("players").getAsJsonObject().get("sample").getAsJsonArray()){
                players.add(e.getAsJsonObject().get("name").getAsString());
            }
            playercount += " (" + StringUtils.join(players, ", ") +")";
        }
        IRCUtils.sendMessage(user, network, channel, "[" + address.getHostString() + ":" + port + "] " + gameVersion + " - " + motd + " - " + playercount, prefix);
    }

}


@@ -4936,16 +4936,83 @@
 nt() %3E 0
+ && response.get(%22players%22).getAsJsonObject().get(%22sample%22) != null
 )%7B%0A     

Fix 1.7.10 Compatibility