/*
 * COPYRIGHT (c) 1998-1999 Jan-Henrik Haukeland, http://www.tildeslash.com/
 */


package ts.mail;

import java.io.*;
import java.util.*;

import ts.mail.DefaultMailModel;
import ts.mail.Mime;
import ts.config.Constant;
import ts.config.Config;
import ts.biff.SafeTerminate;
import ts.biff.MailUtil;


/**  
 * This Class is a FetchAgent but does not use a mailserver for
 * fetching mail, instead it fetches mail by reading and parsing a
 * standard Unix mailbox file (mbox).
 *
 * The <b>getMail</b> method implements the FetchAgents interface
 * method getMail. It returns the content of the mailbox file as a
 * Vector of MailModel objects, where one MailModel represents one
 * mail message from the mailbox file.
 *
 * @see DefaultMailModel
 * @see FetchAgent
 *
 * @author  Jan-Henrik Haukeland &lt;hauk@tildeslash.com&gt;
 * @version $Id: MboxAgent.java,v 1.11 1999/11/26 00:30:55 hauk Exp $ 
 */
public class MboxAgent implements FetchAgent
{

  /** Protocol used by this class */
  protected final String PROTOCOL= "mbox";

  /** The mail box file name */
  private String myMailBox;

  /** Flag for safe termination */
  private boolean canTerminate= true;



  /**
   * Initializes the class with the mailbox filename
   *
   * @param aMailBoxFile The mail box file to parse for mail messages
   */
  public MboxAgent(String aMailBoxFile)
  {
    myMailBox= aMailBoxFile;
  }



  /**
   * Implementation of the SafeTerminate interface
   * @return true if it's safe to terminate
   */
  public boolean canTerminate()
  {
    return canTerminate;
  }



  // ------------- Implementation of interface methods ----------------- //

  
  /** 
   * Implementation of getMail method. This method opens a mailbox file
   * and read mail messages. Each message is put into a MailModel object.
   *
   * @return A Vector with MailModel objects, representing the mbox file
   *
   * @exception GetMailException Is thrown if mail for some reason
   *                             could not be obtained 
   */
  public Vector getMail() throws GetMailException
  {

    /*
     * Check the mailbox file first
     */
    try {
      validateMboxFile();
    } catch (GetMailException ge) {
      // The file does not exist, just return an empty Vector
      if ( ge.getStatus() == GetMailException.WARNING) {
	  return (Vector)null;
      }
      else {
	// mailbox file is invalid, pass on the exception
	throw new GetMailException(ge.getStatus(),
				   ge.getMessage());
      }
    }

    FileInputStream in= null;
    Vector          v=  null;
    
    try {
      // Don't let the application terminate while reading mail
      canTerminate= false;

      in= new FileInputStream(myMailBox);
      
      v= MailParser.parse(in);
      
    }
    catch (GetMailException gm) {
      throw new GetMailException(gm.getStatus(),
				 gm.getMessage());
    }
    catch (IOException e) {
      throw new GetMailException(GetMailException.ERROR,
				 "Error reading mail box file ("+
				 myMailBox+"):"+
				 e.getMessage());
    }
    finally {
      // Now it's ok to terminate
      canTerminate= true;
      
      try {
	in.close(); in= null; //gc pragma
      } catch (Exception e) {
	System.err.println("Error: "+e.getMessage());
	e.printStackTrace();
      }
    }


    return v;
  }



  /**
   * Stop reading mail
   */
  public void stopScan()
  {
    // Left empty
  }
  

  /**
   * @return The protocol used
   */
  public String getProtocol() 
  {
    return PROTOCOL;
  }




  /**
   * Validate the mbox file. If it's not a regular file or if this
   * program has no read permission, throw an exception.
   * 
   * If the mailbox file does not exist or size of mailbox is 0, throw 
   * an exception as well, but only with a warning status, because if 
   * the user does not have any mail, the mailbox file will on some
   * systems not be present.
   *
   * @exception GetMailException Is thrown if the mailbox file 
   *                             is invalid or could not be found
   */
  protected void validateMboxFile() throws GetMailException
  {
    try {
      
      File ftest= new File(myMailBox);

      if ( ! ftest.exists() )
	  throw new GetMailException(GetMailException.WARNING,
				     "Mail box file ("+myMailBox+
				     ") does not exist");
      

      if ( ! ftest.isFile() )
	  throw new GetMailException(GetMailException.ERROR,
				     "Mail box file ("+myMailBox+
				     ") is not a regular file");
      
      if ( ! ftest.canRead() )
	  throw new GetMailException(GetMailException.ERROR,
				     "No permisson to read the "+
				     "Mail box file ("+myMailBox+")");

      if ( ftest.length() == 0 )
	  throw new GetMailException(GetMailException.WARNING,
				     "Mail box file ("+myMailBox+
				     ") is empty");

    }
    catch (NullPointerException ne) {
      throw new GetMailException(GetMailException.ERROR,
				 "Got null value for mbox file name");
    }
    catch (SecurityException se) {
      throw new GetMailException(GetMailException.ERROR,
				 "Cannot stat Mail box file ("+
				 myMailBox+"). Check permission");
    }
  }

}

  
