#include <Vector.h>
#include <ArduinoLog.h>

#include <macros.h>
#include <constants.h>
#include <types.h>
#include <debug.h>

#include "SerialMessage.h"
#include "CommandMessage.h"
#include "bridge.h"

#ifndef SERIAL_COMMAND_PARSE_INTERVAL
#define SERIAL_COMMAND_PARSE_INTERVAL 50
#endif

#define DEBUG_SERIAL_MESSAGES

#ifdef DEBUG_SERIAL_MESSAGES
    #define _DEBUG_MESSAGE_HANDLING(format, ...) Log.verboseln(format, ##__VA_ARGS__)
#else
    #define _DEBUG_MESSAGE_HANDLING(format, ...)
#endif

static CommandMessage *_messages[10];

short SerialMessage::setup()
{
    messages.setStorage(_messages);
    msg = new CommandMessage(0,E_CALLS::EC_NONE,E_MessageFlags::E_MF_NONE);
    return E_OK;
}

CommandMessage *SerialMessage::parse(char *string)
{
    return NULL;
}

short SerialMessage::debug()
{
    return E_OK;
}

String SerialMessage::readStringFromSerial()
{
    String message;
    while (stream.available())
    {
        message = stream.readString();
        message.trim();
    }
    return message;
}

CommandMessage *SerialMessage::read()
{

    String message = readStringFromSerial();
    if (!message.length())
    {
        return NULL;
    }
    _DEBUG_MESSAGE_HANDLING("SerialMessage::read: message: %s", message.c_str());
    if (!msg->matches(message.c_str()))
    {
        _DEBUG_MESSAGE_HANDLING("SerialMessage::read : Invalid message - no match : %s", message.c_str());
        printStringAsHex(message.c_str());
        return NULL;
    }

    bool validMessage = msg->parse(message);
    if (!validMessage)
    {
        _DEBUG_MESSAGE_HANDLING("SerialMessage::read : invalid message - incomplete : %s", message.c_str());
        return NULL;
    }
    return msg;
}

short SerialMessage::loop()
{
    if (now - lastRead < SERIAL_COMMAND_PARSE_INTERVAL)
    {
        return E_OK;
    }
    lastRead = now;
    CommandMessage *msg = read();
    if (msg)
    {
        _DEBUG_MESSAGE_HANDLING("SerialMessage::loop:received message %s", msg->payload);
        if (owner)
        {
            owner->onMessage(msg->id, msg->verb, msg->flags, msg->payload, this);
        }else{
            _DEBUG_MESSAGE_HANDLING("SerialMessage::loop: have no owner");
        }
    }
    return E_OK;
}