#include "protocol/OutgoingAggreGateCommand.h"
#include "IllegalStateException.h"
#include "util/simpleobject/AgString.h"
#include "util/simpleobject/AgDate.h"

static const char CLIENT_COMMAND_SEPARATOR = 0x17;

AgString OutgoingAggreGateCommand::header()
{
    return AgString(AggreGateCommand::START_CHAR);
}

AgString OutgoingAggreGateCommand::footer()
{
    return AgString(AggreGateCommand::END_CHAR);
}

OutgoingAggreGateCommand::OutgoingAggreGateCommand()
    : AggreGateCommand(), paramCount(0)
{
}

OutgoingAggreGateCommand &OutgoingAggreGateCommand::addParam(const AgString &param)
{
    if (paramCount != 0)
    {
        write(reinterpret_cast<const unsigned char*>(&CLIENT_COMMAND_SEPARATOR), 0, sizeof(CLIENT_COMMAND_SEPARATOR));
    }

    if (paramCount == AggreGateCommand::INDEX_ID)
    {
        this->id = param;
    }

    std::vector<unsigned char> data = param.getBytes(UTF8_CHARSET);
    if (data.size() > 0)
    {
        write(&data[0],0,  data.size());
    }
    data.clear();
    paramCount++;
    return *this;
}

AgString OutgoingAggreGateCommand::getId()
{
    return id;
}

void OutgoingAggreGateCommand::constructReply(const AgString &id, const AgString &code)
{
    if (paramCount > 0)
    {
        throw IllegalStateException("Can't construct reply - parameters already added to command");
    }

    addParam(AgString(AggreGateCommand::COMMAND_CODE_REPLY));
    addParam(id);
    addParam(code);
}

void OutgoingAggreGateCommand::constructReply(const AgString &id, const AgString &code, const AgString &message)
{
    constructReply(id, code);
    addParam(DataTableUtils::transferEncode(message));
}

void OutgoingAggreGateCommand::constructReply(const AgString &id, const AgString &code, const AgString &message, const AgString &details)
{
    constructReply(id, code, message);
    addParam(DataTableUtils::transferEncode(details));
}

void OutgoingAggreGateCommand::constructEvent(const AgString &context, const AgString &name, int level, const AgString &encodedDataTable, int64_t eventId, AgDatePtr creationtime, int listener)
{
    addParam(AgString(AggreGateCommand::COMMAND_CODE_MESSAGE));
    addParam(this->id);
    addParam(AgString(AggreGateCommand::MESSAGE_CODE_EVENT));
    addParam(context);
    addParam(name);
    addParam(AgString::fromInt(level));
    addParam(AgString::fromInt64(eventId));
    if (listener > 0)
        addParam(AgString::fromInt(listener));
    else
        addParam("");
    addParam(encodedDataTable);
    addParam(creationtime.get() != NULL ? AgString::fromInt64(creationtime->toTime()) : "");
}


