package com.ubergeek42.weechat.relay.connection;

import com.ubergeek42.weechat.relay.RelayConnectionHandler;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.ArrayList;

public abstract class AbstractConnection implements IConnection {
    String server = null;
    int port = 0;

    Socket sock = null;
    OutputStream out_stream = null;
    InputStream in_stream = null;
    boolean connected = false;
    Object errordata = null;

    ArrayList<RelayConnectionHandler> connectionHandlers = new ArrayList<RelayConnectionHandler>();
    Thread connector = null;

    @Override
    public boolean isConnected() {
        return (sock!= null && !sock.isClosed() && connected);
    }

    @Override
    public int read(byte[] bytes) throws IOException {
        return in_stream.read(bytes);
    }

    @Override
    public void write(byte[] bytes) {
        try {
            out_stream.write(bytes);
        } catch (IOException e) {
            // TODO: better this part
            e.printStackTrace();
        }
    }

    @Override
    public void connect() {
        notifyHandlers(STATE.CONNECTING);

        if (connector.isAlive()) {
            // do nothing
            return;
        }
        connector.start();
    }

    /**
     * Disconnects from the server, and cleans up
     */
    @Override
    public void disconnect() {
        if (!connected) {
            return;
        }
        try {
            // If we're in the process of connecting, kill the thread and let us die
            if (connector.isAlive()) {
                connector.interrupt();
                //connector.stop(); // FIXME: deprecated, should probably find a better way to do this
            }

            // If we're connected, tell weechat we're going away
            if (connected) {
                out_stream.write("quit\n".getBytes());
            }

            // Close all of our streams/sockets
            connected = false;
            if (in_stream != null) {
                in_stream.close();
                in_stream = null;
            }
            if (out_stream != null) {
                out_stream.close();
                out_stream = null;
            }
            if (sock != null) {
                sock.close();
                sock = null;
            }

            // Call any registered disconnect handlers
            notifyHandlers(STATE.DISCONNECTED);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * Register a connection handler to receive onConnected/onDisconnected events
     *
     * @param rch - The connection handler
     */
    @Override
    public void addConnectionHandler(RelayConnectionHandler rch) {
        connectionHandlers.add(rch);
    }

    @Override
    public void notifyHandlers(IConnection.STATE s) {
        for (RelayConnectionHandler rch: connectionHandlers) {
            switch (s) {
                case CONNECTING:
                    rch.onConnecting();
                    break;
                case CONNECTED:
                    rch.onConnect();
                    break;
                case AUTHENTICATED:
                    rch.onAuthenticated();
                    break;
                case DISCONNECTED:
                    rch.onDisconnect();
                    break;
                case ERROR:
                    rch.onError("unknown error", errordata);
                    break;
            }
        }
    }
}

@@ -1473,34 +1473,17 @@
       %7D%0A
-        try %7B%0A    
+%0A
         
@@ -1555,36 +1555,32 @@
  us die%0A        
-    
 if (connector.is
@@ -1582,36 +1582,32 @@
 or.isAlive()) %7B%0A
-    
             conn
@@ -1637,20 +1637,16 @@
         
-    
 //connec
@@ -1724,36 +1724,32 @@
 do this%0A        
-    
 %7D%0A%0A            /
@@ -1812,33 +1812,14 @@
     
-    
-if (connected) %7B%0A    
+try %7B%0A
     
@@ -1869,35 +1869,94 @@
 ));%0A        
+%7D catch (IOException e) %7B%0A            e.printStackTrace();%0A    
     %7D%0A%0A
-    
         // C
@@ -1991,28 +1991,24 @@
 ets%0A        
-    
 connected = 
@@ -2018,28 +2018,24 @@
 se;%0A        
-  
-  
 if (in_strea
@@ -2039,32 +2039,50 @@
 ream != null) %7B%0A
+            try %7B%0A
                 
@@ -2096,32 +2096,67 @@
 am.close();%0A    
+        %7D catch (IOException e) %7B%7D%0A
             in_s
@@ -2169,36 +2169,32 @@
 = null;%0A        
-    
 %7D%0A            if
@@ -2183,28 +2183,24 @@
   %7D%0A        
- 
-   
 if (out_stre
@@ -2205,32 +2205,50 @@
 ream != null) %7B%0A
+            try %7B%0A
                 
@@ -2263,32 +2263,67 @@
 am.close();%0A    
+        %7D catch (IOException e) %7B%7D%0A
             out_
@@ -2337,36 +2337,32 @@
 = null;%0A        
-    
 %7D%0A            if
@@ -2351,28 +2351,24 @@
   %7D%0A        
- 
-   
 if (sock != 
@@ -2367,32 +2367,50 @@
 sock != null) %7B%0A
+            try %7B%0A
                 
@@ -2419,32 +2419,67 @@
 ck.close();%0A    
+        %7D catch (IOException e) %7B%7D%0A
             sock
@@ -2491,28 +2491,24 @@
 ll;%0A        
-    
 %7D%0A%0A         
@@ -2502,28 +2502,24 @@
  %7D%0A%0A        
- 
-   
 // Call any 
@@ -2553,28 +2553,24 @@
 ers%0A        
-    
 notifyHandle
@@ -2597,85 +2597,8 @@
 D);%0A
-        %7D catch (IOException e) %7B%0A            e.printStackTrace();%0A        %7D%0A
     

Fix a few issues when disconnecting