package tech.nevets.dlite;

import javax.net.SocketFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import javax.swing.*;
import java.io.*;
import java.net.MalformedURLException;
import java.net.Socket;
import java.security.KeyStore;
import java.security.SecureRandom;

public class Connection {
    private Socket s;
    private InputStream is;
    private PrintStream out;
    private String username;

    private JTextArea chat;

    public Connection(String username, String address) throws Exception {
        String[] addrSplit = address.split(":");
        if (addrSplit.length != 2) {
            throw new MalformedURLException("Address not formatted 'ip:port'");
        }

        KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
        InputStream tStore = new FileInputStream("./truststore.p12");
        trustStore.load(tStore, "".toCharArray());
        tStore.close();
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(trustStore);

        SSLContext ctx = SSLContext.getInstance("TLS");
        ctx.init(null, tmf.getTrustManagers(), SecureRandom.getInstanceStrong());

        SocketFactory factory = ctx.getSocketFactory();
        s = factory.createSocket(addrSplit[0], Integer.parseInt(addrSplit[1]));

        is = s.getInputStream();
        OutputStream os = s.getOutputStream();
        out = new PrintStream(os);
        this.username = username;
        out.println(username);
    }

    public void sendMessage(String message) {
        out.println(message);
    }

    public void setComponents(JTextArea chat) {
        this.chat = chat;
        new Thread(() -> {
            try {
                is.transferTo(new ChatWriter());
            } catch (IOException ignored) {}
            close();
        }).start();
    }

    public void close() {
        try {
            s.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        ChatWindow.getInstance().resetConnection();
    }

    private class ChatWriter extends OutputStream {
        String buf = "";

        @Override
        public void write(int b) {
            buf += (char) b;
            if (((char) b) == '\n') this.flush();
        }

        @Override
        public void flush() {
            chat.append(buf);
            Notifier.messageReceived(Main.getFrame());
            //Notifier.sendNotification(buf.substring(0, buf.indexOf(">") - 1), buf.substring(buf.indexOf(">")));
            buf = "";
        }
    }
}
