/* Copyright (C) 2006 - 2014 Jan Kundrát <jkt@flaska.net>

   This file is part of the Trojita Qt IMAP e-mail client,
   http://trojita.flaska.net/

   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) version 3 or any later version
   accepted by the membership of KDE e.V. (or its successor approved
   by the membership of KDE e.V.), which shall act as a proxy
   defined in Section 14 of version 3 of the license.

   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, see <http://www.gnu.org/licenses/>.
*/
#include <ctype.h>
#include <QStringList>
#include "Command.h"

namespace Imap
{
namespace Commands
{

QTextStream &operator<<(QTextStream &stream, const Command &cmd)
{
    for (QList<PartOfCommand>::const_iterator it = cmd.cmds.begin(); it != cmd.cmds.end(); ++it) {
        if (it != cmd.cmds.begin()) {
            stream << " ";
        }
        stream << *it;
    }
    return stream << Qt::endl;
}

TokenType howToTransmit(const QByteArray &str)
{
    if (str.length() > 100)
        return LITERAL;

    if (str.isEmpty())
        return QUOTED_STRING;

    TokenType res = ATOM;

    for (int i = 0; i < str.size(); ++i) {
        char c = str.at(i);

        if (!isalnum(c) && c != '-' && c != '_')
            res = QUOTED_STRING;

        if (!isascii(c) || c == '\r' || c == '\n' || c == '\0' || c == '"') {
            return LITERAL;
        }
    }
    return res;
}

QTextStream &operator<<(QTextStream &stream, const PartOfCommand &part)
{
    switch (part.kind) {
    case ATOM:
        stream << part.text;
        break;
    case QUOTED_STRING: {
        QByteArray item = part.text;
        item.replace('\\', "\\\\");
        stream << '"' << item << '"';
    }
    break;
    case LITERAL:
        stream << "{" << part.text.length() << "}" << Qt::endl << part.text;
        break;
    case IDLE:
        stream << "IDLE" << Qt::endl << "[Entering IDLE mode...]";
        break;
    case IDLE_DONE:
        stream << "DONE" << Qt::endl << "[Leaving IDLE mode...]";
        break;
    case STARTTLS:
        stream << "STARTTLS" << Qt::endl << "[Starting TLS...]";
        break;
    case COMPRESS_DEFLATE:
        stream << "COMPRESS DEFLATE" << Qt::endl << "[Starting deflate...]";
        break;
    case ATOM_NO_SPACE_AROUND:
        stream << part.text;
    }
    return stream;
}

}
}
