/**File Name :     GetPage.java
  *
  *Authors   :     Prashanth. K
  *                Shireen Javali
  *
  *Date      :     20/05/2000
  *
  *Function  :     Retrieves the HTTP or FTP pages from
  *                the site to which the url points to
  */                        

import java.io.*;
import java.net.*;
import java.util.StringTokenizer;

public class GetPage 
{

    public Socket cSock;
    String url;
    String fileName;
    int portNo;
    Gui gui;
    

    GetPage(Gui gui)
    {
        this.gui = gui;
        fileName = null;
        url = null;
        
    }

    public long retrieve(String site,long from,String filename)  throws IOException
    {

        RandomAccessFile  outFile   = null;

        fileName = new String(filename);
        url = new String(site);

        try
        {
          outFile = new RandomAccessFile(fileName,"rw");
          System.out.println("file length "+outFile.length());
        }
        catch (FileNotFoundException fe)
        {
           System.out.println(fe);
           return -2;
        }
        catch (IOException ie)
        {
           System.out.println(ie);
           return -2;
           
        }


        StringTokenizer str = new StringTokenizer(url,"\":/",false);

        //check if http or ftp


        if(str.nextToken().equals("http"))
                portNo = 80;
        else
           if(str.nextToken().equals("ftp"))
                portNo = 21;


        if(portNo == 80)
        {

            try 
            {
                URL hostName  = new URL("http://"+str.nextToken());
                cSock = new Socket(hostName.getHost(),portNo);
                cSock.setSoTimeout(32767);

            }
            catch (UnknownHostException e)  
            {
                 System.out.println("UnknownHostException: " + e);
                 return -2;   //unsuccessful
            }
            catch (IOException e)  
            {
    
                System.err.println("IOException: " + e);
                return -2;    //unsuccessful
            }

    


            HttpHeader header = null;
    
            long bytesReceived = from;
    
            DataOutputStream outBound = null;
            DataInputStream inBound = null;
            int bytes = 0;
                  
            try  
            {
                outBound=new DataOutputStream(cSock.getOutputStream());
                inBound=new DataInputStream( cSock.getInputStream());
    
                outBound.writeBytes("GET "+url+"/ HTTP/1.0 \r\nRange:"+
                                        " Bytes="+ from + "-\r\nConnection: close\r\n\r\n");
    
                StringTokenizer reply = new StringTokenizer(inBound.readLine()," ",false);
    
                reply.nextToken();
    
                if(reply.nextToken().startsWith("4"))
                     return -3;
    
    
                header = new HttpHeader();
                if(header.getHeader(inBound) == -2)
                        return -2;
    
                if(header.isRangeSupported)
                     outFile.seek(from);

                byte[] responseLine = new byte[80];
                
            
                while((bytes=inBound.read(responseLine,0,80))!=-1)  
                {
                    outFile.write(responseLine,0,bytes);
                    bytesReceived  += bytes;
                }

                outBound.close();
                inBound.close();
                cSock.close();
                outFile.close();
    
                return -1;   //successful
            }
            catch (InterruptedIOException iioe)  
            {
                System.out.println("InterruptedIOException: "+iioe);
                outFile.close();
                return bytesReceived+1;   //unsuccessful
            }
            catch (IOException ioe)
            {
                System.out.println("IOException: "+ioe);
                outFile.close();
                return bytesReceived+1;   //unsuccessful
            }

        }
        else
        if(portNo == 21)
        {
                DataInputStream inbound = null;
                DataOutputStream outbound = null;

                try 
                {
                    URL hostName  = new URL("ftp://"+str.nextToken());
                    cSock = new Socket(hostName.getHost(),portNo);
                    cSock.setSoTimeout(32767);
    
                }
                catch (SocketException se)
                {
                    System.out.println("Some Socket Exception :" + se);
                    return -2;
                }
                catch (UnknownHostException e)  
                {
                     System.out.println("UnknownHostException: " + e);
                     return -2;   //unsuccessful
                }
                catch (MalformedURLException ue)
                {
                    System.out.println("Some URL Exception :" + ue);
                    return -2;
                }
                catch (IOException ie)
                {
                    System.out.println("Some IO Exception :" + ie);
                    return -2;
                }

                String responseLine;
                try 
                {

                    outbound = new DataOutputStream( cSock.getOutputStream());
                    inbound = new DataInputStream( cSock.getInputStream() );
        
                    if ((responseLine = inbound.readLine()).startsWith("5"))
                    {
                      System.err.println("ERROR: No such host");
                      IOException ie = new IOException("Quitting ftp Process");
                      throw(ie);
                    }
                    while (responseLine.indexOf("-") == 3) responseLine = inbound.readLine();
        
                    outbound.writeBytes("USER anonymous\r\n");
                    if ((responseLine = inbound.readLine()).startsWith("5"))
                    {
                        System.err.println("ERROR: No such user");
                        IOException ie =  new IOException("Quitting ftp Process");
                        throw(ie);                      
                    }
                    while (responseLine.indexOf("-") == 3)
                            responseLine  = inbound.readLine();
        
                    outbound.writeBytes("PASS guest\r\n");
                    if ((responseLine = inbound.readLine()).startsWith("5"))
                    {
                        System.err.println("ERROR: Wrong PassWord");
                        IOException ie = new IOException("Quitting ftp Process");
                        throw(ie);
                    }
                    while (responseLine.indexOf("-") == 3)
                            responseLine  = inbound.readLine();
                }
                catch (UnknownHostException e)  
                {

                    gui.displayMessage("UnknownHostException: " + e);
                }
                catch (IOException e)  
                {
                    System.err.println("IOException: " + e);
                    System.err.println("Check the Address");
                }



                //get the file

                byte responseLines[] = new byte[80];
                String directory = ".";
                try
                {
                    outbound.writeBytes("MODE B\r\n");
        
                    if ((responseLine = inbound.readLine()).startsWith("5"))
                    {
                        gui.displayMessage("Block Mode not possible."+ 
                                  " Trying Stream...");
                        outbound.writeBytes("MODE S\r\n");
                        System.out.println(inbound.readLine());
                    }
                    while (responseLine.indexOf("-") == 3)
                                responseLine = inbound.readLine();
                    
                    outbound.writeBytes("TYPE I\r\n");
        
                    if ((responseLine = inbound.readLine()).startsWith("5"))
                    {
                        System.err.println("ERROR: Wrong Type");
                        IOException ie = new IOException("Quitting ftp Process");
                        throw(ie);
                    }
                    while (responseLine.indexOf("-") == 3)
                                responseLine = inbound.readLine();
        
                    outbound.writeBytes("PASV\r\n");
                    String passive;
                    if ((passive = inbound.readLine()).startsWith("5"))
                    {
                        System.err.println("ERROR: aquiring a passive port");
                        IOException ie = new IOException("Quitting ftp Process");
                        throw(ie);
                    }
                    while (responseLine.indexOf("-") == 3)
                          responseLine = inbound.readLine();
                 
        
                    StringTokenizer token =
                          new StringTokenizer(passive,"    ,()",false);
                    Integer portNum;
                    int p=0;
                    
                    if(token.nextToken().equals("227"))
                    {
                          for(int i = 0; i<7; i++)
                             token.nextToken();
                          portNum = new Integer(token.nextToken());
                          p = portNum.intValue() * 256;
                          portNum = new Integer(token.nextToken());
                          p += portNum.intValue();   
            
                          Socket cSock2 = new Socket(site,p);               
                          DataInputStream inbound1 = new DataInputStream( cSock2.getInputStream() );
        
                          outbound.writeBytes("PWD\r\n");
                          gui.displayMessage(inbound.readLine());
        
                          outbound.writeBytes("RETR " + fileName + "\r\n");
                          System.out.println(fileName);
        
                          if((responseLine = inbound.readLine()).startsWith("5"))
                          {
                            System.err.println("ERROR: No such File");
                            IOException ie = new IOException("Quitting ftp Process");
                            throw(ie);
                          }
                          while (responseLine.indexOf("-") == 3)
                                    responseLine = inbound.readLine();
                  
                          
                          int howMany;
                          File file = new File(directory);
                          file.mkdirs();
        
                          outFile =  new RandomAccessFile(directory + File.separator + fileName,"rw");
                          while ((howMany = inbound1.read(responseLines,0,80)) != -1)
                                    outFile.write(responseLines,0,howMany);
        
                          outFile.close();
        
                          inbound1.close();
        
                          cSock2.close();
                          if (!(responseLine = inbound.readLine()).startsWith("226"))
                          {
                            System.err.println("ERROR: during downloading File"
                                                                        + fileName);
                            System.err.println("Try again");
                          }
                          while (responseLine.indexOf("-") == 3)
                                responseLine = inbound.readLine();
        
        
                    } 
                }
                catch (IOException ioe)  
                {
                    gui.displayMessage("IOException: " + ioe);
                }

        
        }// if ftp

        return -3;
    }// method retrieve

}

