/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 
    ps ax | grep EventNotfierDiscordBot-1.0
    kill $pid (number)

nohup screen -d -m -S nonroot java -Xmx6048M -jar  /home/javatests/ArtificialAutism-1.0.jar
nohup screen -d -m -S nonroot java -Xmx6800M -jar  /home/javatests/ArtificialAutism-1.0.jar

screen -ls (number1)
screen -X -S (number1) quit
 */
package PresentationLayer;

import DataLayer.settings;
import FunctionLayer.CustomError;
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 java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.*;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;


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

    private static void receiveAndSendPacket(DatagramSocket serverSocket, InetAddress ipAddress, int port) throws IOException, CustomError {
        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 getResponseMsg = Datahandler.instance.getResponseMsg(sentence);
        byte[] sendData = getResponseMsg.getBytes("UTF-8");
        int deliver_port = 0;
        switch (port) {
            case 48470:
                deliver_port = 48479;
                break;
            case 48471:
                deliver_port = 48482;
                break;
            case 48472:
                deliver_port = 48476;
                break;
            case 48473:
                deliver_port = 48481;
                break;
        }
        DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, ipAddress, deliver_port);
        serverSocket.send(sendPacket);
        //System.out.println("receiveAndSendPacket send message to port: " + deliver_port);
    }

    public static void handleUDPTraffic(int port) {
        try (DatagramSocket serverSocket = new DatagramSocket(port)) {
            String hostIP = "";
            if (port == 48473 || port == 48471) {
                hostIP = "51.15.159.31";
            } else {
                hostIP = "195.154.53.196";
            }
            InetAddress ipAddress = InetAddress.getByName(hostIP);//used ip'
            while (true) {
                receiveAndSendPacket(serverSocket, ipAddress, port);
            }
        } catch (SocketException | UnknownHostException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (CustomError customError) {
            customError.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        try {
            Datahandler.instance.initiateMYSQL();
            //nohup screen -d -m -S nonroot java -Xmx6900M -jar  /home/javatests/ArtificialAutism-1.0.jar
            //uncomment db fetch when ready, just keep the comment for future reference
            System.out.println("finished initiating MYSQL");
        } catch (SQLException | IOException ex) {
            Logger.getLogger(DiscordHandler.class.getName()).log(Level.SEVERE, null, ex);
        }
        PipelineJMWESingleton.getINSTANCE();
        Datahandler.instance.instantiateAnnotationMapJMWE();
        Datahandler.instance.shiftReduceParserInitiate();
        Datahandler.instance.instantiateAnnotationMap();
        System.out.println("FINISHED ALL ANNOTATIONS");
        Datahandler.instance.updateStringCache();
        //String token = "NTI5NzAxNTk5NjAyMjc4NDAx.Dw0vDg.7-aMjVWdQMYPl8qVNyvTCPS5F_A";
        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(48470, 48471, 48472, 48473);
                handleUDPTraffic(ports.get(j));
            }).start();
        }
        gateway.on(MessageCreateEvent.class).subscribe(event -> {
            if (!FunctionLayer.DoStuff.isOccupied()) {
                FunctionLayer.DoStuff.doStuff(event, usernameBot);
            }
        });
        gateway.onDisconnect().block();
    }
}
