/*
 *      pop.cpp
 *
 *      Copyright 2009 Sebastian Wankerl <far_away@online.de>
 *
 *      This program 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.
 *
 *      This program 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., 51 Franklin Street, Fifth Floor, Boston,
 *      MA 02110-1301, USA.
 */


# include "pop.hpp"

pop3::pop3 (const std::string &u, const std::string &pw, const std::string &server, bool ssl)  :  base_io(u, pw, server, ssl ? 995 : 110, ssl)
{
    user = u;
    password = pw;
}

pop3::~pop3 () {
    result = close (st);
    if (result == 1)
        throw std::runtime_error ("close () failed");
}

int pop3::start () {
    std::string request;
    int counter = 0;
    for (int i = 0; i <= 4; ++i) {
        int temp = recieve(i);
        counter = temp > 0 ? temp : counter;
		if (i == 4)
			break;

        switch (i) {
            case 0: request = "USER " + user; break;
            case 1: request = "PASS " + password; break;
            case 2: request = "STAT"; break;
            case 3: request = "LIST"; break;
        }
        request += "\r\n";
        send_request (request);
    }
    return counter;
}

int pop3::recieve (int step) {
	line.str("");
    int unred_mails = 0;
    for (char c; ssl ? gnutls_record_recv (session, &c, 1) : recv (st, &c, 1, 0) > 0; line << c) {
		if ((step < 4 && c == '\n') || (step >= 4 && line.str().find("\r\n.") != std::string::npos)) {
			if (line.str().find("-ERR") != std::string::npos)
				throw std::runtime_error ("Access denied");
			if (step == 3)
				unred_mails = procedure_string (line.str ());
			else if (step == 4)
				find_unred_mails (line.str());
			else
				break;
			return unred_mails;
		}
    }
    return 0;
}

int pop3::procedure_string (std::string str) {
    int counter = 0;
    unsigned index = str.find (" ");
    if (index != std::string::npos) {
        std::string count_str = str.substr (index + 1, str.find (" ", index+1) - (index+1));
        counter = std::atoi(count_str.c_str());
    }
    return counter;
}

void pop3::find_unred_mails (std::string line) {
	std::vector<std::string> temp_vec;
	boost::erase_head(line, line.find('\n') + 1);
	if (line.length() > 0)
		boost::split(temp_vec, line, boost::is_any_of(" \n"));
	for (unsigned i = 0; i < temp_vec.size(); ++i) {
		if (i % 2 == 0)
			unred_mails.push_back(temp_vec[i]);
	}
	unred_mails.pop_back();
}

bool pop3::get_header(std::string &str, unsigned pos) {
	if (pos < unred_mails.size()) {
		std::string request = "TOP " + unred_mails[pos] + " 0\r\n";
		send_request(request);
		recieve(5);

		str = line.str();
		return true;
	}
	return false;
}

void pop3::set_unred(int) {
	// not necessary
}
