/*
 * $Id: AmMail.cpp,v 1.9 2004/08/16 11:11:30 rco Exp $
 *
 * Copyright (C) 2002-2003 Fhg Fokus
 *
 * This file is part of sems, a free SIP media server.
 *
 * sems is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version
 *
 * For a license to use the ser software under conditions
 * other than those described here, or to purchase support for this
 * software, please contact iptel.org by e-mail at the following addresses:
 *    info@iptel.org
 *
 * sems is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License 
 * along with this program; if not, write to the Free Software 
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "AmMail.h"
#include "AmSmtpClient.h"
#include "AmConfig.h"
#include "AmUtils.h"
#include "log.h"

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>


AmMail::AmMail(const string& _from, const string& _subject,
	       const string& _to, const string& _body, 
	       const string& _header)
    : from(_from), subject(_subject), body(_body), header(_header),
      to(_to), clean_up(0), error_count(0)
{
}

AmMail::~AmMail()
{
    for(Attachements::iterator it = attachements.begin();
	it != attachements.end(); it++){

	fclose(it->fp);
    }
};

AmMailDeamon* AmMailDeamon::_instance=0;

AmMailDeamon* AmMailDeamon::instance()
{
    if(!_instance)
	_instance = new AmMailDeamon();
    return _instance;
}

void AmMailDeamon::on_stop()
{
}

int AmMailDeamon::sendQueued(AmMail* mail)
{
    if(mail->from.empty() || mail->to.empty()){
	ERROR("mail.from('%s') or mail.to('%s') is empty\n",mail->from.c_str(),mail->to.c_str());
	return -1;
    }

//     FILE* tst_fp;
//     for( Attachements::const_iterator att_it = mail->attachements.begin();
// 	 att_it != mail->attachements.end(); ++att_it ){
	
// 	if(!(tst_fp = fopen(att_it->fullname.c_str(),"r"))){
// 	    ERROR("%s\n",strerror(errno));
// 	    return -1;
// 	}
// 	else
// 	    fclose(tst_fp);
//     }

    event_fifo_mut.lock();
    event_fifo.push(mail);
    event_fifo_mut.unlock();
    _run_cond.set(true);
    return 0;
}

void AmMailDeamon::run()
{
    queue<AmMail*> n_event_fifo;
    while(1){

	_run_cond.wait_for();
	sleep(5);

	string server_address = get_ip_from_name(AmConfig::SmtpServerAddress);
	if(server_address.empty()){
	    WARN("Mail deamon could not resolv SMTP server address <%s>\n",
		 AmConfig::SmtpServerAddress.c_str());
	    continue;
	}

	AmSmtpClient smtp;
	if (smtp.connect(server_address,AmConfig::SmtpServerPort)) {
	    
	    WARN("Mail deamon could not connect to SMTP server at <%s:%i>\n",
		 server_address.c_str(),AmConfig::SmtpServerPort);
	    continue;
	}

	event_fifo_mut.lock();
	DBG("Mail deamon starting its work\n");

	while(!event_fifo.empty()){

	    AmMail* cur_mail = event_fifo.front();
	    event_fifo.pop();

	    event_fifo_mut.unlock();

	    bool err = true;
	    try{
		err = smtp.send(*cur_mail);
	    }
	    catch(...){}

	    if(err && (cur_mail->error_count < 3)){
		n_event_fifo.push(cur_mail);
		cur_mail->error_count++;
	    }
	    else {
		if(cur_mail->clean_up)
		    (*(cur_mail->clean_up))(cur_mail);
		delete cur_mail;
	    }
	    event_fifo_mut.lock();
	}

	event_fifo_mut.unlock();
	smtp.disconnect();
	smtp.close();

	if(n_event_fifo.empty()){
	    _run_cond.set(false);
	}
	else {
	    while(!n_event_fifo.empty())
		n_event_fifo.pop();
	}

	DBG("Mail deamon finished\n");
    }
}