/**
 * $RCSfile$
 * $Revision$
 * $Date$
 *
 * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
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;

/**
 * Socket factory for socks4 proxy 
 *  
 * @author Atul Aggarwal
 */
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 socks4ProxifiedSocket(host,port);
        
    }

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

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

    public Socket createSocket( InetAddress address, int port, 
                                InetAddress localAddress, int localPort) 
        throws IOException
    {
        return 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 = proxy.getProxyAddress();
        int proxy_port = proxy.getProxyPort();
        String user = proxy.getProxyUsername();
        String passwd = proxy.getProxyPassword();
        
        try
        {
            socket=new Socket(proxy_host, proxy_port);    
            in=socket.getInputStream();
            out=socket.getOutputStream();
            socket.setTcpNoDelay(true);
            
            byte[] buf=new byte[1024];
            int index=0;

    /*
    1) CONNECT

    The client connects to the SOCKS server and sends a CONNECT request when
    it wants to establish a connection to an application server. The client
    includes in the request packet the IP address and the port number of the
    destination host, and userid, in the following format.

           +----+----+----+----+----+----+----+----+----+----+....+----+
           | VN | CD | DSTPORT |      DSTIP        | USERID       |NULL|
           +----+----+----+----+----+----+----+----+----+----+....+----+
    # of bytes:   1    1      2              4           variable       1

    VN is the SOCKS protocol version number and should be 4. CD is the
    SOCKS command code and should be 1 for CONNECT request. NULL is a byte
    of all zero bits.
    */

            index=0;
            buf[index++]=4;
            buf[index++]=1;

            buf[index++]=(byte)(port>>>8);
            buf[index++]=(byte)(port&0xff);

            try
            {
                InetAddress addr=InetAddress.getByName(host);
                byte[] byteAddress = addr.getAddress();
                for (int i = 0; i < byteAddress.length; i++) 
                {
                    buf[index++]=byteAddress[i];
                }
            }
            catch(UnknownHostException uhe)
            {
                throw new ProxyException(ProxyInfo.ProxyType.SOCKS4, 
                    uhe.toString(), uhe);
            }

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

    /*
    The SOCKS server checks to see whether such a request should be granted
    based on any combination of source IP address, destination IP address,
    destination port number, the userid, and information it may obtain by
    consulting IDENT, cf. RFC 1413.  If the request is granted, the SOCKS
    server makes a connection to the specified port of the destination host.
    A reply packet is sent to the client when this connection is established,
    or when the request is rejected or the operation fails. 

           +----+----+----+----+----+----+----+----+
           | VN | CD | DSTPORT |      DSTIP        |
           +----+----+----+----+----+----+----+----+
    # of bytes:   1    1      2              4

    VN is the version of the reply code and should be 0. CD is the result
    code with one of the following values:

    90: request granted
    91: request rejected or failed
    92: request rejected becasue SOCKS server cannot connect to
    identd on the client
    93: request rejected because the client program and identd
    report different user-ids

    The remaining fields are ignored.
    */

            int len=6;
            int s=0;
            while(s<len)
            {
                int i=in.read(buf, s, len-s);
                if(i<=0)
                {
                    throw new ProxyException(ProxyInfo.ProxyType.SOCKS4, 
                        "stream is closed");
                }
                s+=i;
            }
            if(buf[0]!=0)
            {
                throw new ProxyException(ProxyInfo.ProxyType.SOCKS4, 
                    "server returns VN "+buf[0]);
            }
            if(buf[1]!=90)
            {
                try
                {
                    socket.close();
                }
                catch(Exception eee)
                {
                }
                String message="ProxySOCKS4: server returns CD "+buf[1];
                throw new ProxyException(ProxyInfo.ProxyType.SOCKS4,message);
            }
            byte[] temp = new byte[2];
            in.read(temp, 0, 2);
            return socket;
        }
        catch(RuntimeException e)
        {
            throw e;
        }
        catch(Exception e)
        {
            try
            {
                if(socket!=null)socket.close(); 
            }
            catch(Exception eee)
            {
            }
            throw new ProxyException(ProxyInfo.ProxyType.SOCKS4, e.toString());
        }
    }
}
