#ifndef KOURIER_H
#define KOURIER_H

#include <klog.h>

#include "kmsg.h"
#include "klist.h"
#include "kouriererr.h"

struct KourierTagDef
{
    const uint8_t mTagID;
    const KTag::KTagType mTagType;
};

struct KourierMsgDef
{
    const uint8_t mMsgID;
    const uint8_t mReqCount;
    const uint8_t *mReqTags;
};

struct KourierMetaDef
{
    const uint8_t mTagID;
    const uint8_t mReqCount;
    const uint8_t *mReqTags;
};

struct KourierDictDef
{
    const uint8_t mDictID;
    const uint8_t mDictVer;
    const uint8_t mMsgsCount;
    const uint8_t mTagsCount;
    const uint8_t mMetasCount;
    const KourierMsgDef *mMsgs;
    const KourierTagDef *mTags;
    const KourierMetaDef *mMetas;
};

class Kourier : public cKlog
{
public:
    Kourier(const KourierDictDef *iDictDef);
    KourierErrors * sendMessage(KMsg *msg);
    KMsg * getMessage();
    KourierErrors * bytesIn(const uint8_t *bytes, uint16_t len);
    KourierErrors * bytesOut(uint8_t *bytes, uint16_t *len);
    bool bytesOutReady();
    KourierErrors * checkMessage(KMsg *msg);
    static bool isMeta(const KourierDictDef *dict, uint8_t id);
private:
    KourierErrors * checkMessageTags(const KourierMsgDef *msgdef, uint8_t *msgtags, uint8_t tagcount);
    const KourierMsgDef * findMsgDef(uint8_t id);
    const KourierTagDef * findTagDef(uint8_t id);
    const KourierDictDef *mDictDef;
    KList mInList;
    KList mOutList;
};

#endif
