#include "cbor.h"

bool cbor_add_float(zcbor_state_t *zsd, const char *str, float item)
{
    return zcbor_tstr_encode_ptr(zsd, str, strlen(str)) &&
	zcbor_float16_put(zsd, item);
}

bool cbor_add_double(zcbor_state_t *zsd, const char *str, double item)
{
    return zcbor_tstr_encode_ptr(zsd, str, strlen(str)) &&
	zcbor_float32_put(zsd, item);
}

bool cbor_add_long_double(zcbor_state_t *zsd, const char *str, long double item)
{
    return zcbor_tstr_encode_ptr(zsd, str, strlen(str)) &&
	zcbor_float64_put(zsd, item);
}

bool cbor_add_uint64(zcbor_state_t *zsd, const char *str, uint64_t item)
{
    return zcbor_tstr_encode_ptr(zsd, str, strlen(str)) &&
	zcbor_uint64_put(zsd, item);
}

bool cbor_add_uint32(zcbor_state_t *zsd, const char *str, uint32_t item)
{
    return zcbor_tstr_encode_ptr(zsd, str, strlen(str)) &&
	zcbor_uint32_put(zsd, item);
}

bool cbor_add_int64(zcbor_state_t *zsd, const char *str, int64_t item)
{
    return zcbor_tstr_encode_ptr(zsd, str, strlen(str)) &&
	zcbor_int64_put(zsd, item);
}

bool cbor_add_int32(zcbor_state_t *zsd, const char *str, int32_t item)
{
    return zcbor_tstr_encode_ptr(zsd, str, strlen(str)) &&
	zcbor_int32_put(zsd, item);
}

bool cbor_add_bool(zcbor_state_t *zsd, const char *str, bool item)
{
    return zcbor_tstr_encode_ptr(zsd, str, strlen(str)) &&
	zcbor_bool_put(zsd, item);
}

bool cbor_add_size(zcbor_state_t *zsd, const char *str, size_t item)
{
    return zcbor_tstr_encode_ptr(zsd, str, strlen(str)) &&
	zcbor_size_put(zsd, item);
}


bool cbor_add_undefined(zcbor_state_t *zsd, const char *str)
{
    return zcbor_tstr_encode_ptr(zsd, str, strlen(str)) &&
	zcbor_undefined_put(zsd, NULL);
}

bool cbor_add_nil(zcbor_state_t *zsd, const char *str)
{
    return zcbor_tstr_encode_ptr(zsd, str, strlen(str)) &&
	zcbor_nil_put(zsd, NULL);
}

bool cbor_add_str(zcbor_state_t *zsd, const char *str, const char *item)
{
    return zcbor_tstr_encode_ptr(zsd, str, strlen(str)) &&
    //zcbor_tstr_encode_ptr(zsd, item, strlen(item));
    zcbor_tstr_put_term(zsd, item, strlen(item));
}

bool cbor_add_str1(zcbor_state_t *zsd, const void *var, const char *item)
{
	size_t truc = sizeof(var);
	//bool zcbor_uint_encode(zcbor_state_t *state, const void *input_uint, size_t uint_size);
    return zcbor_uint_encode(zsd, var, 1) &&
    //zcbor_tstr_encode_ptr(zsd, item, strlen(item));
    zcbor_tstr_put_term(zsd, item, strlen(item));
}

bool cbor_add_str2(zcbor_state_t *zsd, uint32_t var, const char *item)
{
	//bool zcbor_uint_encode(zcbor_state_t *state, const void *input_uint, size_t uint_size);
    return zcbor_uint32_put(zsd, var) &&
    //zcbor_tstr_encode_ptr(zsd, item, strlen(item));
    zcbor_tstr_put_term(zsd, item, strlen(item));
}

bool cbor_add_str3(zcbor_state_t *zsd, uint16_t var, const char *item)
{
	//bool zcbor_uint_encode(zcbor_state_t *state, const void *input_uint, size_t uint_size);
    return zcbor_float16_bytes_put(zsd, var) &&
    //zcbor_tstr_encode_ptr(zsd, item, strlen(item));
    zcbor_tstr_put_term(zsd, item, strlen(item));
}




int zcbor_map_decode_bulk(zcbor_state_t *zsd, struct zcbor_map_decode_key_val *map,
	size_t map_size, size_t *matched)
{
	bool ok;
	struct zcbor_map_decode_key_val *dptr = map;
	if (!zcbor_map_start_decode(zsd)) {
		return -EBADMSG;
	}

	*matched = 0;
	ok = true;

	do {
		struct zcbor_string key;
		bool found = false;
		size_t map_count = 0;

		ok = zcbor_tstr_decode(zsd, &key);

		while (ok && map_count < map_size) {
			if (dptr >= (map + map_size)) {
				dptr = map;
			}

			if (key.len == dptr->key.len		&&
			    memcmp(key.value, dptr->key.value, key.len) == 0) {

				if (dptr->found) {
					return -EADDRINUSE;
				}
				if (!dptr->decoder(zsd, dptr->value_ptr)) {
					/* Failure to decode value matched to key
					 * means that either decoder has been
					 * incorrectly assigned or SMP payload
					 * is broken anyway.
					 */
					return -ENOMSG;
				}

				dptr->found = true;
				found = true;
				++dptr;
				++(*matched);
				break;
			}

			++dptr;
			++map_count;
		}

		if (!found && ok) {
			ok = zcbor_any_skip(zsd, NULL);
		}
	} while (ok);

	return zcbor_map_end_decode(zsd) ? 0 : -EBADMSG;
}

bool zcbor_map_decode_bulk_key_found(struct zcbor_map_decode_key_val *map, size_t map_size,
	const char *key)
{
	size_t key_len;
	struct zcbor_map_decode_key_val *dptr = map;

	/* Lazy run, comparing pointers only assuming that compiler will be able to store
	 * read-only string of the same value as single instance.
	 */
	while (dptr < (map + map_size)) {
		if (dptr->key.value == (const uint8_t *)key) {
			return dptr->found;
		}
		++dptr;
	}

	/* Lazy run failed so need to do real comprison */
	key_len = strlen(key);
	dptr = map;

	while (dptr < (map + map_size)) {
		if (dptr->key.len == key_len &&
		    memcmp(key, dptr->key.value, key_len) == 0) {
			return dptr->found;
		}
		++dptr;
	}

	return false;
}

void zcbor_map_decode_bulk_reset(struct zcbor_map_decode_key_val *map, size_t map_size)
{
	for (size_t map_index = 0; map_index < map_size; ++map_index) {
		map[map_index].found = false;
	}
}