#include <QDir>
#include <QFile>
#include <QTextStream>

#include "dcantispam.h"

DCAntiSpam *g_pAntiSpam;

DCAntiSpam::DCAntiSpam()
{
    g_pAntiSpam = this;
}

DCAntiSpam::~DCAntiSpam()
{
    gray_list.clear();
    white_list.clear();
    black_list.clear();

    g_pAntiSpam = NULL;
}

void DCAntiSpam::slotObjectChangeState(QString obj, AntiSpamObjectState from, AntiSpamObjectState to)
{
    if (from == to)
        return;

    if ((from == eIN_BLACK && !black_list.contains(obj)) ||
        (from == eIN_WHITE && !white_list.contains(obj)) ||
        (from == eIN_GRAY  && !gray_list.contains(obj))    )
    {
        return;
    }

    QList<QString> *from_list = &white_list;
    QList<QString> *to_list   = &black_list;

    if (from != eIN_WHITE){
        if (from == eIN_BLACK)
            from_list = &black_list;
        else
            from_list = &gray_list;
    }\

    if (to != eIN_BLACK){
        if (to == eIN_WHITE)
            to_list = &white_list;
        else
            to_list = &gray_list;
    }

    from_list->removeAll(obj);

    if (to_list->contains(obj)){//just remove from source list
        return;
    }

    to_list->append(obj);

}

bool DCAntiSpam::isInAny(QString obj)
{
    return ( isInBlack(obj) || isInGray(obj) || isInWhite(obj) );
}

bool DCAntiSpam::isInBlack(QString obj)
{
    return (black_list.contains(obj));
}

bool DCAntiSpam::isInGray(QString obj)
{
    return ( gray_list.contains(obj) );
}

bool DCAntiSpam::isInWhite(QString obj)
{
    return ( white_list.contains(obj) );
}

void DCAntiSpam::move(QString obj, AntiSpamObjectState state)
{
    if (isInAny(obj)){
        AntiSpamObjectState from;

        if (isInBlack(obj))
            from = eIN_BLACK;
        else if (isInGray(obj))
            from = eIN_GRAY;
        else
            from = eIN_WHITE;

        slotObjectChangeState(obj, from, state);
    }
    else{
        if (state == eIN_BLACK)
            black_list << obj;
        else if (state == eIN_GRAY)
            gray_list << obj;
        else
            white_list << obj;
    }
}

inline void DCAntiSpam::addToList(QList<QString> &source, QList<QString> &dest)
{
    for (int i = 0; i < dest.size(); i++){
        if (!source.contains(dest.at(i)))
            source << dest.at(i);
    }
}

inline void DCAntiSpam::remFromList(QList<QString> &from, QList<QString> &what)
{
    for (int i = 0; i < what.size(); i++){
        int index = from.indexOf(what.at(i));

        if (index != -1)
            from.removeAt(index);
    }
}

void DCAntiSpam::addToBlack(QList<QString> &list)
{
    addToList(black_list, list);
}

void DCAntiSpam::addToGray(QList<QString> &list)
{
    addToList(gray_list, list);
}

void DCAntiSpam::addToWhite(QList<QString> &list)
{
    addToList(white_list, list);
}

void DCAntiSpam::remFromBlack(QList<QString> &list)
{
    remFromList(black_list, list);
}

void DCAntiSpam::remFromGray(QList<QString> &list)
{
    remFromList(gray_list, list);
}

void DCAntiSpam::remFromWhite(QList<QString> &list)
{
    remFromList(white_list, list);
}

QList<QString> DCAntiSpam::getBlack()
{
    return black_list;
}

QList<QString> DCAntiSpam::getGray()
{
    return gray_list;
}

QList<QString>  DCAntiSpam::getWhite()
{
    return white_list;
}

void DCAntiSpam::loadLists()
{
    if (!gray_list.empty()  ||
        !black_list.empty() ||
        !white_list.empty() )
    {
        return;
    }
    loadBlack();
    loadWhite();
    loadGray();
}

void DCAntiSpam::saveLists()
{
    saveBlack();
    saveGray();
    saveWhite();
}

void DCAntiSpam::loadBlack()
{
    readFile(QDir::homePath() + "/.eiskaltdc/blacklist", black_list);
}

void DCAntiSpam::loadGray()
{
    readFile(QDir::homePath() + "/.eiskaltdc/graylist", gray_list);
}

void DCAntiSpam::loadWhite()
{
    readFile(QDir::homePath() + "/.eiskaltdc/whitelist", white_list);
}

void DCAntiSpam::saveBlack()
{
    saveFile(QDir::homePath() + "/.eiskaltdc/blacklist", black_list);
}

void DCAntiSpam::saveGray()
{
    saveFile(QDir::homePath() + "/.eiskaltdc/graylist", gray_list);
}

void DCAntiSpam::saveWhite()
{
    saveFile(QDir::homePath() + "/.eiskaltdc/whitelist", white_list);
}

void DCAntiSpam::readFile(QString path, QList<QString> &list)
{
    if (!QFile::exists(path))
        return;

    QFile file(path);

    if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
        return;

    QTextStream in(&file);

    while (!in.atEnd()){
        QString line = in.readLine();

        line.replace("\n", "");

        if (line == "")
            continue;

        list << line;
    }

    file.close();
}

void DCAntiSpam::saveFile(QString path, QList<QString> &list)
{
    QFile file(path);

    if (!file.open(QIODevice::WriteOnly))
        return;

    QTextStream out(&file);

    for (int i = 0; i < list.size(); i++)
        out << list.at(i) << "\n";

    file.close();
}

void DCAntiSpam::loadSettings()
{
    QFile file(QDir::homePath() + "/.eiskaltdc/antispam");

    if (!file.exists() || !file.open(QIODevice::ReadOnly | QIODevice::Text)){
        key     = "10";
        phrase  = "5+5=?";

        return;
    }

    QTextStream in(&file);

    while (!in.atEnd()){
        QString line = in.readLine();

        if (line.indexOf("|ANTISPAM_PHRASE|") != -1){
            line = line.right(line.length()-17);
            line.replace("\n", "");

            if (line == "")
                phrase = "5+5=?";
            else
                phrase = line;
        }
        else if (line.indexOf("|ANTISPAM_KEY|") != -1){
            line = line.right(line.length()-14);
            line.replace("\n", "");

            if (line == "")
                key = "10";
            else
                key = line;
        }
    }

    file.close();
}

void DCAntiSpam::saveSettings()
{
    QFile file(QDir::homePath() + "/.eiskaltdc/antispam");

    if (!file.open(QIODevice::WriteOnly))
        return;

    QTextStream out(&file);

    out << "|ANTISPAM_PHRASE|" << phrase << "\n";
    out << "|ANTISPAM_KEY|"    << key    << "\n";

    file.close();
}

void DCAntiSpam::setPhrase(QString &phrase)
{
    if (phrase == ""){
        this->phrase = (phrase = "5+5=?");
    }
    else
        this->phrase = phrase;
}

void DCAntiSpam::setKey(QString &key)
{
    if (key == "")
        this->key = (key = "10");
    else
        this->key = key;
}

QString DCAntiSpam::getKey() const
{
    return key;
}

QString DCAntiSpam::getPhrase() const
{
    return phrase;
}

void DCAntiSpam::clearAll()
{
    clearBlack();
    clearGray();
    clearWhite();
}

void DCAntiSpam::clearBlack()
{
    black_list.clear();
}

void DCAntiSpam::clearGray()
{
    gray_list.clear();
}

void DCAntiSpam::clearWhite()
{
    white_list.clear();
}
