<?php

/**
 * Migrate adapter for the mbox format. Only
 * migrates users and their mail.
 *
 * Takes a path to a csv file as the argument to the
 * constructor. CSV file shall be in the following
 * format (those marked * are compulsory, others can
 * be left blank):
 *
 * path-to-mbox*, folder-name, account-name*, password*, first-name, last-name, password-question, birth-date, address, city, state, zip, country, home-phone, work-phone, mobile-phone, quota, group
 *
 * Where "account-name" is the name of the Atmail
 * account that should be created, "path-to-mbox"
 * is the path to that user's mbox file and 
 * "folder-name" is the name of the Atmail folder
 * the mail should be saved to. This last item is
 * optional and if not given will default to "INBOX".
 * If an folder is given and it does not exist then
 * it will be created.
 *
 * @author Brad Kowalczyk <brad@staff.atmail.com>
 */
 
class Atmail_Migrate_Adapter_Mbox implements Atmail_Migrate_Adapter_Interface {

	private $_currentUser;
	private $_isMboxDir = false;
	private $_mbox;
	private $_folder;
	
	
	public function __construct($path)
	{
		$this->_fh = fopen($path, 'r');
	}
	
	public function fetchUser()
	{	
		if (false === $line = fgetcsv($this->_fh, 10000, ",")) {
			return false;
		}
		
		if (is_dir($line[0])) {
            $this->_isMboxDir = true;
            $this->_mboxes = glob("$line[0]/*");
		} else {
            // Open file handle to user's mbox file
            $this->_mbox = fopen($line[0], 'r');
		}
		
		$this->_currentUser = $user;
			
		$user = new Atmail_Migrate_Data_User(array_slice($line, 2));
		return $user;
	}
	
	public function fetchEmail()
	{
        if ($this->_isMboxDir) {
            if (!$this->_iterateMbox()) {
                return false;
            }
        }
        
		if (feof($this->_mbox)) {
			return false;
		}
		
		$msg = '';
		$timestamp = '';
		$skip = false;
		
		while (false !== $line = fgets($this->_mbox)) {

            // UW-IMAP stores folder information inside the mbox file, we need to ignore this
            if (preg_match('/^Subject:\s+DON\'T DELETE THIS MESSAGE -- FOLDER INTERNAL DATA/i', $line)) {
                $msg = '';
                $skip = true;
            }
            
	        if (preg_match('/^From .*?([a-zA-Z]{3} \d{1,2} \d\d:\d\d:\d\d \d{4})$/', $line, $m)) {
	        	$timestamp = strtotime($m[1]);
	        	$skip = false;
	        	if (!empty($msg)) {
					break;
				}
				
	        } elseif(!$skip) {
	            $msg .= "$line";
	        }
	    }
	    
	    // Only return if we ever found what looks like an email,
	    // avoid returning garbage
	    $email = new Atmail_Migrate_Data_Email;
	    $email->setContent($msg);
	    $email->setFolder($this->_folder);
	    $email->addFlag("SEEN");
	    $email->setTimestamp($timestamp);
	    
	    return $email;
	}
	
	protected function _iterateMbox()
	{   
        // If we have not yet opened an mbox or the current
        // one is at end of file, open the next one
        if (!is_resource($this->_mbox) || feof($this->_mbox)) {
            
            // No mboxes left to open
            if (count($this->_mboxes) == 0) {
                return false;
            }
            
            // get the next mbox from the list
            $mbox = array_pop($this->_mboxes);
            
            $this->_mbox = fopen($mbox, "r");
            $this->_folder = preg_replace("/\.(mbox|mbx)$/", "", basename($mbox));
            return true;
        }
        
        // must be still reading current mbox
        return true;
	}
	
	public function fetchContact()
	{
		return false;
	}
	
	public function fetchCalEvent()
	{
		return false;
	}

}
