// 
// Decompiled by Procyon v0.6.0
// 

package org.jline.builtins.telnet;

import java.util.Iterator;
import java.util.logging.Level;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.List;
import java.util.logging.Logger;

public abstract class Connection extends Thread
{
    private static final Logger LOG;
    private static int number;
    private boolean dead;
    private List<ConnectionListener> listeners;
    private ConnectionData connectionData;
    
    public Connection(final ThreadGroup tcg, final ConnectionData cd) {
        super(tcg, "Connection" + ++Connection.number);
        this.connectionData = cd;
        this.listeners = new CopyOnWriteArrayList<ConnectionListener>();
        this.dead = false;
    }
    
    @Override
    public void run() {
        try {
            this.doRun();
        }
        catch (final Exception ex) {
            Connection.LOG.log(Level.SEVERE, "run()", ex);
        }
        finally {
            if (!this.dead) {
                this.close();
            }
        }
        Connection.LOG.log(Level.FINE, "run():: Returning from " + this.toString());
    }
    
    protected abstract void doRun() throws Exception;
    
    protected abstract void doClose() throws Exception;
    
    public ConnectionData getConnectionData() {
        return this.connectionData;
    }
    
    public synchronized void close() {
        if (this.dead) {
            return;
        }
        try {
            this.dead = true;
            this.doClose();
        }
        catch (final Exception ex) {
            Connection.LOG.log(Level.SEVERE, "close()", ex);
        }
        try {
            this.connectionData.getSocket().close();
        }
        catch (final Exception ex) {
            Connection.LOG.log(Level.SEVERE, "close()", ex);
        }
        try {
            this.connectionData.getManager().registerClosedConnection(this);
        }
        catch (final Exception ex) {
            Connection.LOG.log(Level.SEVERE, "close()", ex);
        }
        try {
            this.interrupt();
        }
        catch (final Exception ex) {
            Connection.LOG.log(Level.SEVERE, "close()", ex);
        }
        Connection.LOG.log(Level.FINE, "Closed " + this.toString() + " and inactive.");
    }
    
    public boolean isActive() {
        return !this.dead;
    }
    
    public void addConnectionListener(final ConnectionListener cl) {
        this.listeners.add(cl);
    }
    
    public void removeConnectionListener(final ConnectionListener cl) {
        this.listeners.remove(cl);
    }
    
    public void processConnectionEvent(final ConnectionEvent ce) {
        for (final ConnectionListener cl : this.listeners) {
            switch (ce.getType()) {
                case CONNECTION_IDLE: {
                    cl.connectionIdle(ce);
                    continue;
                }
                case CONNECTION_TIMEDOUT: {
                    cl.connectionTimedOut(ce);
                    continue;
                }
                case CONNECTION_LOGOUTREQUEST: {
                    cl.connectionLogoutRequest(ce);
                    continue;
                }
                case CONNECTION_BREAK: {
                    cl.connectionSentBreak(ce);
                    continue;
                }
                case CONNECTION_TERMINAL_GEOMETRY_CHANGED: {
                    cl.connectionTerminalGeometryChanged(ce);
                    continue;
                }
            }
        }
    }
    
    static {
        LOG = Logger.getLogger(Connection.class.getName());
    }
}
