#include <sys/types.h>

#include "output.h"
#include "../../../common/commands.h"
#include "bitwise.h"


enum GetoutputData {
	GO_BLOCK_ID_L,
	GO_BLOCK_ID_H,
	GO_OUTPUT_ID_L,
	GO_OUTPUT_ID_H,
	GO_DATA_SIZE
};

/* Creates data and metadata for a setcontrol packet
 * Returns data size.
 */
ssize_t EncodeGetOutput(
        struct metadata * m,        /* data_len and msg_type will be populated*/
        uint8_t * data,             /* Output buffer */
        size_t data_size,           /* Max buffer size */
        const char * msg)          /* Message to encode */
{
	m->msg_type = GETOUTPUT_ID;
	m->data_len = GO_DATA_SIZE;

	if (data_size < GO_DATA_SIZE) {
		return -1;
	}

	uint16_t block, output;

	sscanf(msg, "getoutput %hu %hu", &block, &output);

	data[GO_BLOCK_ID_L] = LSByte16(block);
	data[GO_BLOCK_ID_H] = MSByte16(block);
	data[GO_OUTPUT_ID_L] = LSByte16(output);
	data[GO_OUTPUT_ID_H] = MSByte16(output);

	return GO_DATA_SIZE;
}

enum ResponseData {
	RESP_BLOCK_ID_L,
	RESP_BLOCK_ID_H,
	RESP_OUTPUT_ID_L,
	RESP_OUTPUT_ID_H,
	RESP_VAL_1,
	RESP_VAL_2,
	RESP_VAL_3,
	RESP_VAL_4,
	RESP_DATA_SIZE
};

/* Decode a metadata and data to populate a controller.
 * Returns bytes written to msg, -1 on failure.
 */
int DecodeResponseOutput(
        char * msg,     /* Decoded controller message */
        const struct metadata * m,          /* Metadata to aid in decoding */
        const uint8_t * data)               /* Data to decode */
{
	if (m->data_len < RESP_DATA_SIZE) {
		return -1;
	}
	if (m->msg_type != RESPOUTPUT_ID) {
		return -1;
	}

	return sprintf(msg, "getoutput %hu %hu %f\n", 
		BytesTo16(data[RESP_BLOCK_ID_L], data[RESP_BLOCK_ID_H]), 
		BytesTo16(data[RESP_OUTPUT_ID_L], data[RESP_OUTPUT_ID_H]), 
		BytesToFloat(data[RESP_VAL_1], data[RESP_VAL_2],
			data[RESP_VAL_3], data[RESP_VAL_4]));
}