<?
App::import('Sanitize');
class VaultShell extends Shell {
    /* vault.php - To be run in CLI via Cron. Fetches the mail from a certain mailbox, searches for a CMC Technologies Enquiry Numbeer
	 * then loads the data into the 'emails' table and the attachments in the 'email_attachments' table.
	 * Emails are discared or moved to a subfolder once processed
    */


    var $uses = array('Enquiry', 'Email', 'EmailAttachment');

    function main() {

        /******************************************************
         * Config Variables
         * *****************************************************/
        $testing = 1; //Whether to actually move the emails. 1=test, 0=production
        /* Setup Connection to the IMAP server */
        $username = 'vault';
        $password = 'xjdYOsmJWc37'; /* The password for the account to be checked */
        $email_dir = '/var/www/cakephp/app/emails';



        $ripmime_path = '/usr/local/bin/ripmime';


        if($testing == 1) {
            $email_dir = '/Users/karlcordes/Sites/quotenik/app/emails';
            $ripmime_path = '/opt/local/bin/ripmime';
            $mbox = imap_open("{192.168.0.8:143}INBOX", $username, $password) or die("can't connect: " . imap_last_error());
        }
        else {
            $mbox = imap_open("{192.168.0.8:143/novalidate-cert}INBOX", $username, $password) or die("can't connect: " . imap_last_error());
        }



        $MC = imap_check($mbox);
        $number_of_messages = $MC->Nmsgs;

        echo "Number of messages to Process ".$number_of_messages."\n";
        
        if($number_of_messages == 0) {
            exit(0);
        }

        $enquiries = $this->Enquiry->find('all', array('recursive'=>0,'fields' => array('Enquiry.title', 'Enquiry.id')));



        foreach ($enquiries as $enq) {
            $enqNumber = $enq['Enquiry']['title'];
            $id = $enq['Enquiry']['id'];
            $enquiryList[$enqNumber] = $id;
        }

        $storedArray = array();
        $discardArray = array();


        //exit(0);

        
        /* Loop through the messages and sort them into ones to be processed or discarded */
      
            for($i=1; $i<100;$i++) {
//for($i=1; $i <= $number_of_messages; $i++) {
            $this_header = imap_headerinfo($mbox, $i);
            $message = $this->getMessage($mbox, $i, $this_header);

            //echo "Checking msg number: $i\tSubject: ".$message['subject']."\n";
            echo "Checking msg number: $i\n";

            $enqID = $this->checkIfValidEnquiry($message['subject'], $enquiryList);


            if($enqID != false) {
                echo "Found Message with enquiry ID: ".$enqID." Processing.\n";
                //Process it and store the message and its attachments.

                //Generate a Uniqid for this email.
              //  $uniqid = $this->getUniqId($email_dir);

                $this->Email->create();
                $this->data['Email']['enquiry_id'] = $enqID;
                $this->data['Email']['to'] = $message['to'];
                $this->data['Email']['cc'] = $message['cc'];
                $this->data['Email']['from'] = $message['from'];
                $this->data['Email']['date'] = $message['date'];
                $this->data['Email']['subject'] = $message['subject'];
                $this->data['Email']['body'] = "";
                $this->data['Email']['plainbody'] = "";

                $structure = imap_fetchstructure($mbox, $i);
                $attachments = 1;
                if (empty($structure->parts)) { /* A single part message. No attachments and is plain text */
                    $this->data['Email']['body'] = imap_body($mbox, $i);
                }
                else {
                    $attachments = $this->fetchBodyAttachments($mbox, $i, $email_dir, $uniqid, $ripmime_path);
                    if($attachments != 1) {
                        foreach ($attachments as $attachment) {
                            if($attachment['type'] == 'text/html') { //Assuming All HTML attachments are the body of the email
                                if(file_exists($email_dir.'/'.$uniqid.'/'.$attachment['name'])) {
                                    $filecontents = file_get_contents($email_dir.'/'.$attachment['name']);
                                    $size = filesize($email_dir.'/'.$attachment['name']);
                                    $this->data['Email']['body'] .= $filecontents;
                                }

                            }
                            if($attachment['type'] == 'text/plain') { //Found plain text
                                if(file_exists($email_dir.'/'.$attachment['name'])) {
                                    $filecontents = file_get_contents($email_dir.'/'.$attachment['name']);
                                    $size = filesize($email_dir.'/'.$attachment['name']);
                                    $this->data['Email']['plainbody'] .= $filecontents;
                                }

                            }
                        }

                    }
                }


                if( ($this->data['Email']['body'] != "") || ($this->data['Email']['plainbody'] != "") || ($attachments != 1) ) {

                    if($this->Email->save($this->data)) {
                        $email_id = $this->Email->id;
                        if($attachments != 1) {
                            foreach ($attachments as $attachment) {
                                if(file_exists($email_dir.'/'.$attachment['name']) != FALSE) {

                                    if( ($attachment['type'] != 'text/html') && ($attachment['type'] != 'multipart/mixed') &&
                                            ($attachment['type'] != 'multipart/alternative') &&
                                            ($attachment['type'] != 'multipart/report') &&
                                            ($attachment['type'] != 'text/plain') &&
                                            ($attachment['type'] != 'text/rfc822-headers') &&
                                            ($attachment['type'] != 'message/delivery-status')


                                    ) {
                                        $this->EmailAttachment->create();
                                        $this->data['EmailAttachment']['email_id'] = $email_id;
                                        $this->data['EmailAttachment']['name'] = $attachment['name'];
                                        $this->data['EmailAttachment']['type'] = $attachment['type'];
                                        $this->data['EmailAttachment']['size'] = filesize($email_dir.'/'.$attachment['name']);
                                        $this->data['EmailAttachment']['filename'] = $email_dir.'/'.$attachment['name'];
                                        if ($this->EmailAttachment->save($this->data)) {
                                            echo "Saved file successfully to database\n";
                                        }
                                        else {
                                            echo "Error saving the file to the DB\n";
                                        }
                                    }

                                }
                            }
                        }
                        echo "Email stored in the DB under enquiry ID".$enqID." Message will now be deleted\n";

                        //$storedArray[] = $i;


                    }
                    else {
                        echo 'Unable to save the Email\n';
                    }
                } else {
                    echo "Unable to find either HTML or Plaintext body to this email. Ignoring it";
                }
            } else {
                /* Can't find a valid-looking CMC Enquiry Number. Move the message to the discarded folder
             * I may change this to simply delete the emails. This will do for now, but it's doubling up on the storage for useless files.
             * */

               // $discardArray[] = $i;

                
            }




        }




        /* Finished working with the IMAP server. Make the changes and close the connection */

        //if($testing == 0) {



            echo "Tidying up now. Moving messages to Stored or Discarded\n";


            reset($discardArray);
            reset($storedArray);

            $numberToStore = count($storedArray);
            $numberToDiscard= count($discardArray);


            if($numberToStore > 0) {
                echo "Got $numberToStore messages to store\n";
                $storeSet = implode(",", $storedArray); 
                imap_mail_move($mbox, $storeSet, 'INBOX/Stored');
            }

            if($numberToDiscard > 0) {
                echo "Going to discard $numberToDiscard messages\n";
                $discardSet = implode(",",$discardArray);
            
                imap_mail_move($mbox, $discardSet, 'INBOX/Discarded');
            }





            
            
            
        //}

        imap_expunge($mbox);
        imap_close($mbox);
    }



    /*
    * Fetches the body and attachments from a MIME encoded email. Uses ripmime to do the decoding
    *
    */

    function fetchBodyAttachments($mailbox, $msg_number, $email_dir, $ripmime_path) {



        $email_file = $email_dir.'/'.$uniqid.'.eml';
        imap_savebody($mailbox, $email_file, $msg_number);
        $command = "$ripmime_path -i $email_file -d $email_dir --prefix --paranoid -v --verbose-contenttype";

        $output = array();
        exec($command, $output, $status);

        /* Check the $output array and find the filenames of the attachments */

        if($status == 0) {
            $attachments = array();

            for($i=0, $j=0; $i< count($output); $i++, $j++) {
                $words = explode(' ', $output[$i]);
                $type = explode('=', $words[1]);
                $name = explode('=', $words[2]);

                if($type[1] == "" || $name[1] == "") {
                    continue;
                }

                $attachments[$j]['type'] = $type[1];
                $attachments[$j]['name'] = $name[1];
                //echo "in message number $msg_number ($uniqid): found attachment ".$attachments[$j]['name'].' '.$attachments[$j]['type']."\n";
            }
            unlink($email_file);
            return $attachments;

        }
        else {
            unlink($email_file);
            return 1;
        }
    }


    function getMessage($mbox, $msgnumber, $headers) {

        $subject = $headers->subject;
        //$subject = iconv_mime_decode($subject, 0, "ISO-8859-1//IGNORE");
        // $subject = mb_convert_encoding($subject, "ISO-8859-1");
        // $subject = mb_convert_encoding($subject, "UTF-8");
        $subject = mb_decode_mimeheader($subject);

        $date = $headers->date;
        $recipients = $this->getRecipients($headers);
        $message['subject'] = $subject;
        $message['date'] = $date;
        $message['to'] = $recipients['to'];
        $message['from'] = $recipients['from'];
        $message['cc'] = $recipients['cc'];
        return $message;

    }
    /* get Recipients from the headers of an email  */
    function getRecipients($headers) {

        $recipients = array();
        $recipients['to'] = "";
        $recipients['from'] = "";
        $recipients['cc'] = "";

        if(isset($headers->to)) {
            $to = $headers->to;
            if(count($to) > 0) {
                foreach ($to as $id => $object) {
                    $recipients['to'] .= "$object->mailbox@$object->host ";
                }
            }
        }
        if(isset($headers->cc)) {
            $cc = $headers->cc;
            if(count($cc) > 0) {
                foreach ($cc as $id => $object) {
                    $recipients['cc'] .= "$object->mailbox@$object->host ";
                }

            }
        }

        if(isset($headers->from)) {
            $from = $headers->from;
            if(count($from) > 0) {
                foreach ($from as $id => $object) {
                    $recipients['from'] .= "$object->mailbox@$object->host";
                }
            }
        }

        return $recipients;
    }


    function getBody($mbox, $msgnumber) {
        $structure = imap_fetchstructure($mbox, $msgnumber);
        if (!empty($structure->parts)) {
            $body = $this->getParts($structure->parts, $mbox, $msgnumber);
        }
        else {
            $body = imap_body($mbox, $msgnumber); /* Or get the plaintext */
        }
        return $body;
    }

    function checkIfValidEnquiry($subject, &$enqList) {
        $subject = iconv_mime_decode($subject, 0, "ISO-8859-1");

        $output = array();
//	$decoded_subject = iconv_mime_decode($subject, 2, "ISO-8859-1");

        preg_match("/CMC\d+([NVQWSOT]|ACT|NT)E\d+-\d+/", $subject, $output);


        if(isset($output[0])) { //Found a valid-looking Enquiry Number
            $fetched_enquirynumber = $output[0];

            if(array_key_exists($fetched_enquirynumber, $enqList)) { //check if it actually exists.
                $enqid = $enqList[$fetched_enquirynumber];

                return $enqid;
            }
            else {
                return false;
            }
        }
        else {
            return false;
        }

    }


}
?>
