/* FTPURLConnection.java --
   Copyright (C) 2003, 2004, 2006  Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
 
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package gnu.java.net.protocol.ftp;

import gnu.classpath.SystemProperties;
import gnu.java.net.GetLocalHostAction;

import java.io.FilterInputStream;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.URL;
import java.net.URLConnection;
import java.security.AccessController;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * An FTP URL connection.
 *
 * @author Chris Burdess (dog@gnu.org)
 */
public class FTPURLConnection
  extends URLConnection
{

  /**
   * The connection managing the protocol exchange.
   */
  protected FTPConnection connection;

  protected boolean passive;
  protected int representationType;
  protected int fileStructure;
  protected int transferMode;

  /**
   * Constructs an FTP connection to the specified URL.
   * @param url the URL
   */
  public FTPURLConnection(URL url)
  {
    super(url);
    passive = true;
    representationType = FTPConnection.TYPE_BINARY;
    fileStructure = -1;
    transferMode = -1;
  }

  /**
   * Establishes the connection.
   */
  public void connect()
    throws IOException
  {
    if (connected)
      {
        return;
      }
    String host = url.getHost();
    int port = url.getPort();
    String username = url.getUserInfo();
    String password = null;
    if (username != null)
      {
        int ci = username.indexOf(':');
        if (ci != -1)
          {
            password = username.substring(ci + 1);
            username = username.substring(0, ci);
          }
      }
    else
      {
        username = "anonymous";
        GetLocalHostAction a = new GetLocalHostAction();
        InetAddress localhost = AccessController.doPrivileged(a);
        password = SystemProperties.getProperty("user.name") + "@" +
          ((localhost == null) ? "localhost" : localhost.getHostName());
      }
    connection = new FTPConnection(host, port);
    if (!connection.authenticate(username, password))
      {
        throw new SecurityException("Authentication failed");
      }
    connection.setPassive(passive);
    if (representationType != -1)
      {
        connection.setRepresentationType(representationType);
      }
    if (fileStructure != -1)
      {
        connection.setFileStructure(fileStructure);
      }
    if (transferMode != -1)
      {
        connection.setTransferMode(transferMode);
      }
  }
  
  /**
   * This connection supports doInput.
   */
  public void setDoInput(boolean doinput)
  {
    doInput = doinput;
  }

  /**
   * This connection supports doOutput.
   */
  public void setDoOutput(boolean dooutput)
  {
    doOutput = dooutput;
  }
  
  /**
   * Returns an input stream that reads from this open connection.
   */
  public InputStream getInputStream()
    throws IOException
  {
    if (!connected)
      {
        connect();
      }
    String path = url.getPath();
    if (connection.changeWorkingDirectory(path))
      {
        return this.new ClosingInputStream(connection.list(null));
      }
    else
      {
        return this.new ClosingInputStream(connection.retrieve(path));
      }
  }
  
  /**
   * Returns an output stream that writes to this connection.
   */
  public OutputStream getOutputStream()
    throws IOException
  {
    if (!connected)
      {
        connect();
      }
    String path = url.getPath();
    return this.new ClosingOutputStream(connection.store(path));
  }

  public String getRequestProperty(String key)
  {
    if ("passive".equals(key))
      {
        return Boolean.toString(passive);
      }
    else if ("representationType".equals(key))
      {
        switch (representationType)
          {
          case FTPConnection.TYPE_ASCII:
            return "ASCII";
          case FTPConnection.TYPE_EBCDIC:
            return "EBCDIC";
          case FTPConnection.TYPE_BINARY:
            return "BINARY";
          }
      }
    else if ("fileStructure".equals(key))
      {
        switch (fileStructure)
          {
          case FTPConnection.STRUCTURE_FILE:
            return "FILE";
          case FTPConnection.STRUCTURE_RECORD:
            return "RECORD";
          case FTPConnection.STRUCTURE_PAGE:
            return "PAGE";
          }
      }
    else if ("transferMode".equals(key))
      {
        switch (transferMode)
          {
          case FTPConnection.MODE_STREAM:
            return "STREAM";
          case FTPConnection.MODE_BLOCK:
            return "BLOCK";
          case FTPConnection.MODE_COMPRESSED:
            return "COMPRESSED";
          }
      }
    return null;
  }

  public Map<String, List<String>> getRequestProperties()
  {
    Map<String, List<String>> map = new HashMap<String, List<String>>();
    addRequestPropertyValue(map, "passive");
    addRequestPropertyValue(map, "representationType");
    addRequestPropertyValue(map, "fileStructure");
    addRequestPropertyValue(map, "transferMode");
    return map;
  }

  private void addRequestPropertyValue(Map<String, List<String>> map,
                                       String key)
  {
    String value = getRequestProperty(key);
    ArrayList<String> l = new ArrayList<String>();
    l.add(value);
    map.put(key, l);
  }
  
  public void setRequestProperty(String key, String value)
  {
    if (connected)
      {
        throw new IllegalStateException();
      }
    if ("passive".equals(key))
      {
        passive = Boolean.valueOf(value).booleanValue();
      }
    else if ("representationType".equals(key))
      {
        if ("A".equalsIgnoreCase(value) ||
            "ASCII".equalsIgnoreCase(value))
          {
            representationType = FTPConnection.TYPE_ASCII;
          }
        else if ("E".equalsIgnoreCase(value) ||
                 "EBCDIC".equalsIgnoreCase(value))
          {
            representationType = FTPConnection.TYPE_EBCDIC;
          }
        else if ("I".equalsIgnoreCase(value) ||
                 "BINARY".equalsIgnoreCase(value))
          {
            representationType = FTPConnection.TYPE_BINARY;
          }
        else
          {
            throw new IllegalArgumentException(value);
          }
      }
    else if ("fileStructure".equals(key))
      {
        if ("F".equalsIgnoreCase(value) ||
            "FILE".equalsIgnoreCase(value))
          {
            fileStructure = FTPConnection.STRUCTURE_FILE;
          }
        else if ("R".equalsIgnoreCase(value) ||
                 "RECORD".equalsIgnoreCase(value))
          {
            fileStructure = FTPConnection.STRUCTURE_RECORD;
          }
        else if ("P".equalsIgnoreCase(value) ||
                 "PAGE".equalsIgnoreCase(value))
          {
            fileStructure = FTPConnection.STRUCTURE_PAGE;
          }
        else
          {
            throw new IllegalArgumentException(value);
          }
      }
    else if ("transferMode".equals(key))
      {
        if ("S".equalsIgnoreCase(value) ||
            "STREAM".equalsIgnoreCase(value))
          {
            transferMode = FTPConnection.MODE_STREAM;
          }
        else if ("B".equalsIgnoreCase(value) ||
                 "BLOCK".equalsIgnoreCase(value))
          {
            transferMode = FTPConnection.MODE_BLOCK;
          }
        else if ("C".equalsIgnoreCase(value) ||
                 "COMPRESSED".equalsIgnoreCase(value))
          {
            transferMode = FTPConnection.MODE_COMPRESSED;
          }
        else
          {
            throw new IllegalArgumentException(value);
          }
      }
  }

  public void addRequestProperty(String key, String value)
  {
    setRequestProperty(key, value);
  }

  class ClosingInputStream
    extends FilterInputStream
  {

    ClosingInputStream(InputStream in)
    {
      super(in);
    }

    public void close()
      throws IOException
    {
      super.close();
      connection.logout();
    }
    
  }

  class ClosingOutputStream
    extends FilterOutputStream
  {

    ClosingOutputStream(OutputStream out)
    {
      super(out);
    }

    public void close()
      throws IOException
    {
      super.close();
      connection.logout();
    }
    
  }

}

