/*-------------------------------------------------------------------------*/
/**
 [Project ]: 프레임웍 기반 그룹웨어 시제품 개발
 
 [Date] : 1999. 9. 3
 [Source file]: com/etri/groupware/mail/MailReceiver.java
 [Vesion] : 1.0
 */
/*--------------------------------------------------------------------------*/



// Source file: com/etri/groupware/mail/MailReceiver.java
package com.etri.groupware.mail;

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

import javax.mail.*;
import javax.mail.internet.*;
import javax.mail.search.*;
import javax.activation.*;

import com.etri.groupware.*;


public class ReceiveMailServerManager  implements ReceiveMailServerManagerInterface {
    private String host;

    private String id;
    private String password;
    private boolean debugFlag = false;
	
	private String protocol="imap";
	
	private Session session = null;	
	private Store store = null ;
	private Folder folder = null;
	private Folder dfolder = null;
    
    
    /**
       @roseuid 37C1D86702DA
     */
    public ReceiveMailServerManager( String host,   String id,  String password)   throws Exception {
    	this.host = host;
    	this.id = id;
    	this.password = password;    	
    	
    	connect();
    }
	
	public ReceiveMailServerManager() {}
	
	public void connect(String host,   String id,  String password) throws Exception {
		this.host = host;
    	this.id = id;
    	this.password = password;    	
		
		Properties sysProperties = System.getProperties();
        session = Session.getDefaultInstance(sysProperties, null);
        session.setDebug(debugFlag);

        // Connect to host
        //
        store = session.getStore(protocol);
        store.connect(host, -1, id, password);		
	}
	
	
	protected  void connect() throws Exception {
		Properties sysProperties = System.getProperties();
        session = Session.getDefaultInstance(sysProperties, null);
        session.setDebug(debugFlag);

        // Connect to host
        //
        store = session.getStore(protocol);
        store.connect(host, -1, id, password);
	}
	
	public void disconnect() throws Exception {
		
		if ( folder != null) {
			folder.close(false);
		}
        store.close();
	}
    
    /**
       @roseuid 37C1D8C30001
     */
    public Message[] receiveMail() throws Exception {
       
    	return receiveMail("INBOX", 1, -1);    	
    }
    
    /**
       @roseuid 37C1F0A4026E
     */
    public Message[] receiveMail( String srcFolder)  throws Exception {
    
    		return receiveMail(srcFolder, 1, -1);  
    }
	
	
	public ResultStatus addMail(String srcFolder, Message m) throws Exception {
		
		Message[] ms = new Message[1];
		
		ms[0] = m;
				
		return addMail(srcFolder, ms);

	}
		
	public ResultStatus addMail(String srcFolder, Message[] m) throws Exception{
		
		
		System.out.println(" Add Mail To : " + srcFolder );
		
		if (folder != null ) {
   			folder.close(false);
   		}
		
		Folder folder = store.getFolder(srcFolder);
			
   		if (folder == null || !folder.exists()) {
        	System.out.println("Invalid folder: " + folder.getName());
	   			   			
        	return new ResultStatus(ResultStatus.FAILURE, "Invalid Source Folder");
    	}

    	folder.open(Folder.READ_WRITE);
    	
    	folder.appendMessages(m);
    	
    	System.out.println(" Append Message Succeeded " );

		folder.close(true);
		
		return	new ResultStatus(ResultStatus.SUCCESS, "add Message Success");
		
	}
	
    
    /**
       @roseuid 37C1F0BE00B3
     */
    public Message[] receiveMail( String srcFolder,  int fromIndex,  int endIndex) throws Exception {
      	
        

        // Open the default folder
        //
    	if (folder != null ) {
    		folder.close(false);
    	}
    	
        folder = store.getDefaultFolder();
        if (folder == null){
            throw new NullPointerException("No default mail folder");
        }  

        folder = folder.getFolder(srcFolder);
        
    	if (folder == null) {
            throw new NullPointerException("Unable to get folder: " + folder);
    	}

        // Get message count
        //
        folder.open(Folder.READ_WRITE);
        int totalMessages = folder.getMessageCount();
        if (totalMessages == 0)
        {
            
            return null;
        }
    	else {    		
    		
    		if (endIndex == -1 ) {
    			endIndex = totalMessages;
    		}
    	}
        
        // Get attributes & flags for all messages
        //
        javax.mail.Message[] messages = folder.getMessages(fromIndex, endIndex);
    	
        FetchProfile fp = new FetchProfile();
        fp.add(FetchProfile.Item.ENVELOPE);
        fp.add(FetchProfile.Item.FLAGS);
        fp.add("X-Mailer");
        folder.fetch(messages, fp);

        // Process each message
        //
    
    	/*
        for (int i = 0; i < messages.length; i++)
        {
            if (!messages[i].isSet(Flags.Flag.SEEN))    

        	    messages[i].setFlag(Flags.Flag.DELETED, true); 
        }
        */
    
   	
    	return messages;    	

    	
    }
	
	public ResultStatus removeMail(String srcFolder, int mailNumber) throws Exception {
		
		return removeMail(srcFolder,  mailNumber, mailNumber );
	}
	
	public ResultStatus removeMail(String srcFolder, int fromIndex, int endIndex ) throws Exception{
		
		
			if (folder != null ) {
    			folder.close(false);
    		}
		
			Folder folder = store.getFolder(srcFolder);
			
	   		if (folder == null || !folder.exists()) {
	        	System.out.println("Invalid folder: " + folder.getName());
	   			   			
	        	return new ResultStatus(ResultStatus.FAILURE, "Invalid Source Folder");
	    	}

	    	folder.open(Folder.READ_WRITE);

	    	int count = folder.getMessageCount();
	    
			if (count == 0) { // No messages in the source folder
				System.out.println(folder.getName() + " is empty");
			// Close folder, store and return
				folder.close(false);
			
				return new ResultStatus(ResultStatus.SUCCESS, "Source Folder is empty");
	   		 }
	   		 
	   		 	if (endIndex == -1) {
				endIndex = count;
	    	}

	    	// Get the message objects to copy
	    	Message[] msgs = folder.getMessages(fromIndex, endIndex);
	    	System.out.println("Removing " + msgs.length + " messages");

	    	if (msgs.length != 0) {
				
				folder.setFlags(msgs, new Flags(Flags.Flag.DELETED), true);

				// Dump out the Flags of the moved messages, to insure that
				// all got deleted
				for (int i = 0; i < msgs.length; i++) {
		    		if (!msgs[i].isSet(Flags.Flag.DELETED))
						System.out.println("Message # " + msgs[i] + " not deleted");
				}
	   	 	}
	    

		folder.close(true);
		
		return new ResultStatus(ResultStatus.SUCCESS);
	}	
	
	
	public ResultStatus copyMail(String srcFolder, String dstFolder, int mailNumber ) throws Exception{
		
		return copyMail( srcFolder, dstFolder, mailNumber, mailNumber );
	}
	
	public ResultStatus copyMail( String srcFolder, String dstFolder, int fromIndex, int endIndex) throws Exception{
		
		
		return null;		
	}	

	
	public ResultStatus moveMail(String srcFolder, String dstFolder , int mailNumber ) throws Exception{
		
		return moveMail(  srcFolder, dstFolder, mailNumber, mailNumber);
		
	}
	
	public ResultStatus moveMail( String srcFolder, String dstFolder, int fromIndex, int endIndex ) throws Exception{
		
			if (folder != null ) {
    			folder.close(false);
    		}
			if (dfolder != null) {
				dfolder.close(false);
			}
		  // Open source Folder
		
	    	Folder folder = store.getFolder(srcFolder);
			
	   		if (folder == null || !folder.exists()) {
	        	System.out.println("Invalid folder: " + folder.getName());
	   			   			
	        	return new ResultStatus(ResultStatus.FAILURE, "Invalid Source Folder");
	    	}

	    	folder.open(Folder.READ_WRITE);

	    	int count = folder.getMessageCount();
	    
			if (count == 0) { // No messages in the source folder
				System.out.println(folder.getName() + " is empty");
			// Close folder, store and return
				folder.close(false);
			
				return new ResultStatus(ResultStatus.SUCCESS, "Source Folder is empty");
	   		 }

	    // Open destination folder, create if reqd
	    	Folder dfolder = store.getFolder(dstFolder);
	    	if (!dfolder.exists()){
				dfolder.create(Folder.HOLDS_MESSAGES);
	    	}

	    	if (endIndex == -1) {
				endIndex = count;
	    	}

	    	// Get the message objects to copy
	    	Message[] msgs = folder.getMessages(fromIndex, endIndex);
	    	System.out.println("Moving " + msgs.length + " messages");

	    	if (msgs.length != 0) {
				folder.copyMessages(msgs, dfolder);
				folder.setFlags(msgs, new Flags(Flags.Flag.DELETED), true);

				// Dump out the Flags of the moved messages, to insure that
				// all got deleted
				for (int i = 0; i < msgs.length; i++) {
		    		if (!msgs[i].isSet(Flags.Flag.DELETED))
						System.out.println("Message # " + msgs[i] + " not deleted");
				}
	   	 	}
	    
		folder.close(true);
		dfolder.close(false);
		
		return new ResultStatus(ResultStatus.SUCCESS);
   	 		
	} // end of moveMail method	

	
	public Message[] searchMail(String srcFolder, SearchData searchData ) throws Exception{
		
		if (folder != null ) {
    		folder.close(false);
    	}
		
		Folder folder = store.getDefaultFolder();
		
		if (folder == null ) {
			System.out.println("Can't find Default folder");
			return null;
		}
		
		folder = folder.getFolder(srcFolder);
		
		if (folder == null ) {
			System.out.println("Can't find " + srcFolder + "  folder");
			return null;
		}
		
		folder.open(Folder.READ_ONLY);
		
		javax.mail.search.SearchTerm term = null;
		
		
		// Search by Subject
		if ( searchData.getSubject() != null ) 
	       	term = new SubjectTerm(searchData.getSubject());
		
		// Search mail by Sender address
	    if (searchData.getFrom() != null) {
	    	
			FromStringTerm fromTerm = new FromStringTerm(searchData.getFrom());
	    	
			if (term != null) {
				
		    	if (searchData.getOrFlag()){
					term = new OrTerm(term, fromTerm);
		    	}
		    	else{
					term = new AndTerm(term, fromTerm);
		    	}
			}
			else{
		    	term = fromTerm;
			}
	    }
		
		// Search mail by received date
	    if (searchData.getDate() != null) {
	    	ReceivedDateTerm dateTerm =  new ReceivedDateTerm(ComparisonTerm.EQ, searchData.getDate());
	    	
			if (term != null) {
		    	if (searchData.getOrFlag()){
					term = new OrTerm(term, dateTerm);
		    	}
		    	else{
					term = new AndTerm(term, dateTerm);
		    	}
			}
			else{
		    	term = dateTerm;
			}
	    }
		
		//  Body content Search Restricted as following 
		//  (1) single-part messages whose primary-type is Text OR 
		//  (2) multipart/mixed messages whose first body-part's primary-type is Text. 
		
		if (searchData.getBodyPattern() != null) {
	    	BodyTerm bodyTerm =  new BodyTerm(searchData.getBodyPattern());
	    	
			if (term != null) {
		    	if (searchData.getOrFlag()){
					term = new OrTerm(term, bodyTerm);
		    	}
		    	else{
					term = new AndTerm(term, bodyTerm);
		    	}
			}
			else{
		    	term = bodyTerm;
			}
	    }		

	    Message[] msgs = folder.search(term);
	    System.out.println("FOUND " + msgs.length + " MESSAGES");
	    
		if (msgs.length == 0) { // no match
	    	return null;
	    }

		 // Use a suitable FetchProfile
	    FetchProfile fp = new FetchProfile();
	    fp.add(FetchProfile.Item.ENVELOPE);
	    folder.fetch(msgs, fp);
		
		return msgs;
		
	}
    
    /**
       @roseuid 37B464D2033A
     */
    public void setDebug( boolean state) {
    	this.debugFlag = debugFlag;
    }
}