package org.jivesoftware.smack.proxy;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.net.SocketFactory;

public class Socks4ProxySocketFactory extends SocketFactory {
   private ProxyInfo proxy;

   public Socks4ProxySocketFactory(ProxyInfo proxy) {
      this.proxy = proxy;
   }

   public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
      return this.socks4ProxifiedSocket(host, port);
   }

   public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
      return this.socks4ProxifiedSocket(host, port);
   }

   public Socket createSocket(InetAddress host, int port) throws IOException {
      return this.socks4ProxifiedSocket(host.getHostAddress(), port);
   }

   public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
      return this.socks4ProxifiedSocket(address.getHostAddress(), port);
   }

   private Socket socks4ProxifiedSocket(String host, int port) throws IOException {
      Socket socket = null;
      InputStream in = null;
      OutputStream out = null;
      String proxy_host = this.proxy.getProxyAddress();
      int proxy_port = this.proxy.getProxyPort();
      String user = this.proxy.getProxyUsername();

      try {
         socket = new Socket(proxy_host, proxy_port);
         in = socket.getInputStream();
         out = socket.getOutputStream();
         socket.setTcpNoDelay(true);
         byte[] buf = new byte[1024];
         int index = false;
         int index = 0;
         int index = index + 1;
         buf[index] = 4;
         buf[index++] = 1;
         buf[index++] = (byte)(port >>> 8);
         buf[index++] = (byte)(port & 255);

         int i;
         try {
            InetAddress addr = InetAddress.getByName(host);
            byte[] byteAddress = addr.getAddress();

            for(i = 0; i < byteAddress.length; ++i) {
               buf[index++] = byteAddress[i];
            }
         } catch (UnknownHostException var16) {
            throw new ProxyException(ProxyInfo.ProxyType.SOCKS4, var16.toString(), var16);
         }

         if (user != null) {
            System.arraycopy(user.getBytes(), 0, buf, index, user.length());
            index += user.length();
         }

         buf[index++] = 0;
         out.write(buf, 0, index);
         int len = 6;

         for(int s = 0; s < len; s += i) {
            i = in.read(buf, s, len - s);
            if (i <= 0) {
               throw new ProxyException(ProxyInfo.ProxyType.SOCKS4, "stream is closed");
            }
         }

         if (buf[0] != 0) {
            throw new ProxyException(ProxyInfo.ProxyType.SOCKS4, "server returns VN " + buf[0]);
         } else if (buf[1] != 90) {
            try {
               socket.close();
            } catch (Exception var15) {
            }

            String message = "ProxySOCKS4: server returns CD " + buf[1];
            throw new ProxyException(ProxyInfo.ProxyType.SOCKS4, message);
         } else {
            byte[] temp = new byte[2];
            in.read(temp, 0, 2);
            return socket;
         }
      } catch (RuntimeException var17) {
         throw var17;
      } catch (Exception var18) {
         try {
            if (socket != null) {
               socket.close();
            }
         } catch (Exception var14) {
         }

         throw new ProxyException(ProxyInfo.ProxyType.SOCKS4, var18.toString());
      }
   }
}
