package PresentationLayer;

import DataLayer.settings;
import FunctionLayer.Datahandler;
import FunctionLayer.PipelineJMWESingleton;
import com.sun.tools.javac.util.List;
import discord4j.core.DiscordClient;
import discord4j.core.GatewayDiscordClient;
import discord4j.core.event.domain.message.MessageCreateEvent;
import edu.stanford.nlp.pipeline.StanfordCoreNLP;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.*;
import java.sql.SQLException;


/**
 * @author install1
 */
public class DiscordHandler {

    private static void receiveAndSendPacket(DatagramSocket serverSocket, InetAddress ipAddress, int port,
                                             Datahandler datahandler, StanfordCoreNLP stanfordCoreNLP, StanfordCoreNLP stanfordCoreNLPSentiment) throws IOException {
        byte[] receiveData = new byte[4096];
        DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
        try {
            serverSocket.receive(receivePacket);
        } catch (IOException e) {
            e.printStackTrace();
        }
        String sentence = new String(receivePacket.getData(), 0,
                receivePacket.getLength());
        sentence = sentence.replace("clientmessage:", "");
        String ResponseMsg = datahandler.getResponseMsg(sentence, "", stanfordCoreNLP, stanfordCoreNLPSentiment,
                true);
        byte[] sendData = ResponseMsg.getBytes("UTF-8");
        int deliver_port = 0;
        switch (port) {
            case 48475:
                deliver_port = 48470;
                break;
            case 48476:
                deliver_port = 48471;
                break;
            case 48477:
                deliver_port = 48472;
                break;
            case 48478:
                deliver_port = 48473;
                break;
        }
        DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, ipAddress, deliver_port);
        serverSocket.send(sendPacket);
    }

    public static void handleUDPTraffic(int port, Datahandler datahandler,
                                        StanfordCoreNLP stanfordCoreNLP, StanfordCoreNLP stanfordCoreNLPSentiment) {

        try (DatagramSocket serverSocket = new DatagramSocket(port)) {

            String hostIP = "195.154.53.196";
            if (port == 48477 || port == 48478) {
                hostIP = "51.158.20.245";
            }
            InetAddress ipAddress = InetAddress.getByName(hostIP);//used ip'
            while (true) {
                receiveAndSendPacket(serverSocket, ipAddress, port, datahandler, stanfordCoreNLP, stanfordCoreNLPSentiment);
            }
        } catch (SocketException | UnknownHostException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws IOException, SQLException {
        Datahandler datahandler = new Datahandler();
        datahandler.initiateMYSQL();

        PipelineJMWESingleton.getINSTANCE();
        StanfordCoreNLP stanfordCoreNLP = datahandler.pipeLineSetUp();
        StanfordCoreNLP stanfordCoreNLPSentiment = datahandler.shiftReduceParserInitiate();
        System.out.println("FINISHED ALL ANNOTATIONS");
        datahandler.updateStringCache();
        System.out.println("updatedstring cache");
        String token = new settings().getDiscordToken();
        final DiscordClient client = DiscordClient.create(token);
        final GatewayDiscordClient gateway = client.login().block();
        String usernameBot = gateway.getSelf().block().getUsername();
        int autismbotCount = 4;
        //make sure not to use ports that are already occupied.
        for (int i = 0; i < autismbotCount; i++) {
            final int j = i;
            new Thread(() -> {
                List<Integer> ports = List.of(48475, 48476, 48477, 48478);
                handleUDPTraffic(ports.get(j), datahandler, stanfordCoreNLP, stanfordCoreNLPSentiment);
            }).start();
        }
        gateway.on(MessageCreateEvent.class).subscribe(event -> {
            FunctionLayer.DoStuff.doStuff(event, usernameBot, datahandler, stanfordCoreNLP, stanfordCoreNLPSentiment);
        });
        gateway.onDisconnect().block();
    } //3.1.1 discord4j version
}
