package JavaAgent.agent;

import java.io.*;
import java.net.*;
import java.awt.*;

/**
 * Static class which provides functionality for copying remote files to
 * local files, creating directories, writing byte arrays
 * to local files and reading byte arrays from remote files. <p>
 *
 * <hr>
 * Copyright (c) 1995, H. Robert Frost, Stanford University.
 * All rights reserved.<p>
 * Copyright (c) 1996, H. Robert Frost, Enterprise Integration Technologies,
 * Inc. All rights reserved.<p>
 *
 * RESTRICTED RIGHTS LEGEND: Use, duplication or disclosure by the 
 * Government is subject to restrictions as set forth in 
 * subparagraph(c)(1)(ii) of the Rights in Technical Data and Computer
 * Software clause at DFARS 252.227-7013 and in similar clauses in the
 * FAR and NASA FAR supplement.<p>
 * 
 * This software is bound by the terms and conditions listed in the
 * attached <a href="../LICENSE">LICENSE file</A>.
 * <hr>
 * @author <A HREF="http://cdr.stanford.edu/html/people/frost-bio.html"> Rob Frost</A>
 * @version 0.3 5/21/96 for Java(tm) Language Version 1.0.2
 */

public class FileIO {

  /**
   * Creates the specified local directory.
   * @param path Absolute path for directory.   
   * @return File object if successful or null
   */

  public static File mk_local_dir(String path) throws IOException {
    File dir = new File(path);
    dir.mkdir();
    return dir;
  }

  /**
   * Make a local copy of a remote file. If the local file exists, will either
   * ignore the copy request, overwrite the file or append depending on the
   * exists_action parameter which will have the values "leave", "overwrite"
   * or "append". If "overwrite", the file is first deleted then recreated 
   * with the remote contents.
   * @param remote_file URL of the remote file, includes remote file name.
   * @param path Absolute path for local destination.
   * @param name File name.
   * @param exists_action Action if local file already exists.
   * @return File object if successful or null.
   */
  
  public static File remote_copy(URL remote_file, File path, String name,
				 int exists_action) throws IOException {
    File f = new File(path, name);
    if(f.exists()){
      switch(exists_action){
      case AgentParams.OVERWRITE:
	try {
	  f.delete();
	} catch (SecurityException e){}
	return copy_to_file(remote_file, f, false);
      case AgentParams.APPEND:
	return copy_to_file(remote_file, f, true);
      }
    }
    return copy_to_file(remote_file, f, false);
  }

  /**
   * Copy to a new or existing file.
   */

  private static protected File copy_to_file(URL remote_file, File f, boolean append) throws IOException {
    byte	buffer[] = new byte[1024];
    int	n, total = 0;;
    
    URLConnection url_conn = remote_file.openConnection();
    InputStream is = remote_file.openStream();
    RandomAccessFile raf = new RandomAccessFile(f,"rw");
    if(append){
      long length = raf.length();
      raf.seek(length);
    }
    while ((n = is.read(buffer, 0, buffer.length)) >= 0) {
      raf.write(buffer,0,n);
      total += n;
    }
    is.close();
    raf.close();
    return f;
  }
  
  /**
   * Writes a bite array to a local file. Returns a reference to the file.
   * @param data Bytes to write
   * @param path Absolute path of local file.
   * @param name Name of file
   * @param append If the file already exists, should data be appended?
   * @return Destination file.
   */
  
  public static File write_to_file(byte[] data, File path, String name,boolean append) throws IOException{
    File f = null;
    f = new File(path,name);
    RandomAccessFile raf = new RandomAccessFile(f,"rw");
    if(append){
      long length = raf.length();
      raf.seek(length);
    }
    raf.write(data,0,data.length);
    raf.close();
    return f;
  }

  /**
   * Reads a bite array from a URL.
   * @param source URL to read from.
   * @return bytes read.
   */
  
  public static byte[] read_from_URL(URL source) throws IOException {
    byte	bytes[] = new byte[4096];
    byte	buffer[] = new byte[1024];
    int	n;
    int	totalBytes = 0;
    
    InputStream is = source.openStream();
    while ((n = is.read(buffer, 0, buffer.length)) >= 0) {
      if (totalBytes + n >= bytes.length) {
	byte	newbytes[] = new byte[((bytes.length + n) * 3) / 2];
	
	System.arraycopy(bytes, 0, newbytes, 0, totalBytes);
	
	bytes = newbytes;
      }
      System.arraycopy(buffer, 0, bytes, totalBytes, n);
      totalBytes += n;
    }
    return bytes;
  }
  
}
