#include "parsed_doc_serializer.h"
#include <google/protobuf/messagext.h>

namespace NRTYServer {
    THolder<TParsedDoc> TParsedDocSerializer::Deserialize(const TBlob& blob) const {
        try {
            THolder<TParsedDoc> pd(new TParsedDoc);
            TMemoryInput input(blob.AsCharPtr(), blob.Size());
            ::google::protobuf::io::TProtoSerializer::Load(&input, *pd);
            return pd;
        } catch (...) {
            ythrow yexception() << "incorrect proto usage: " << CurrentExceptionMessage().data();
        }
    }

    TBlob TParsedDocSerializer::Serialize(const TParsedDoc& doc) const {
        try {
            TBufferOutput out;
            ::google::protobuf::io::TProtoSerializer::Save(&out, doc);
            return TBlob::FromBuffer(out.Buffer());
        } catch (...) {
            FAIL_LOG("Can't serialize doc");
        }
    }

    THolder<TParsedDocument> TParsedDocumentSerializer::Deserialize(const TBlob& blob) const {
        try {
            THolder<TParsedDoc> pd(Slave.Deserialize(blob));
            THolder<TParsedDocument> result(new TParsedDocument(Config));
            if (!result->FillFromProto(*pd, Command, ParseContext)) {
                return nullptr;
            }
            return result;
        } catch (...) {
            ythrow yexception() << "Corrupted document: " << CurrentExceptionMessage();
        }
    }

    TBlob TParsedDocumentSerializer::Serialize(const TParsedDocument& doc) const {
        TParsedDoc pd;
        doc.MergeToProto(pd, SerializeContext);
        return Slave.Serialize(pd);
    }

    TParsedDocumentSerializer::TParsedDocumentSerializer(const TRTYServerConfig& config, const TDocSerializeContext& serializeCxt, const TDocParseContext& parseCtx, TMessage::TMessageType command)
        : Config(config)
        , SerializeContext(serializeCxt)
        , ParseContext(parseCtx)
        , Command(command)
    {}
}
