#include "protocol_abstract.h"

#include <saas/library/behaviour/behaviour.h>
#include <saas/util/logging/exception_process.h>


NRTYServer::TReply IReplier::BuildRTYReply() const
{
    NRTYServer::TReply reply;
    reply.SetMessageId(MessageId);
    reply.SetStatus(Status);
    reply.SetStatusMessage(ErrorMessage);
    return reply;
}


IReplier::IReplier(ITransaction& transaction, ui64 messageId, const TInstant& constructionTime /*= Now()*/)
    : IRTYReplierAbstract(transaction)
    , MessageId(messageId)
    , Status(NRTYServer::TReply::INTERNAL_ERROR)
    , Created(constructionTime)
{

}

void IReplier::SetStatus(NRTYServer::TReply::TRTYStatus status, const TString& errorMessage) {
    if (!!errorMessage) {
        DEBUG_LOG << "action=status_message;status=" << NRTYServer::TReply_TRTYStatus_Name(status) << ";message=" << errorMessage << Endl;
    }
    Status = status;
    ErrorMessage = errorMessage;
}

void IReplier::Reply() {
    TRY
        const TString& status = NRTYServer::TReply_TRTYStatus_Name(GetStatus());
        const ui64 duration = (Now() - Created).MilliSeconds();
        const ui16 httpCode = GetBehaviour((NRTYServer::TReply::TDispStatus)GetStatus()).HttpCode;
        if (MessageId) {
            if (DoReply())
                DEBUG_LOG << "REPLY MessageId = " << MessageId << " Status = " << NRTYServer::TReply::TRTYStatus_Name(Status) << " (" << ErrorMessage << "); duration=" << duration << Endl;
            else
                DEBUG_LOG << "Can't send reply for message(" << MessageId << "). Reply will not be send; duration=" << duration << Endl;
        } else {
            DEBUG_LOG << "Message has no MessageId. Reply will not be sent; duration=" << duration << Endl;
        }

        LogReply(MessageId, status, httpCode, duration, ErrorMessage);
        if (Status == NRTYServer::TReply::INTERNAL_ERROR) {
            FATAL_LOG << "Document from message " << MessageId << " status is INTERNAL_ERROR" << Endl;
        }
    CATCH("While reply")
}
