/*
 * Copyright (c) 2019 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */
#include <zephyr/sys/sys_heap.h>
#include <zephyr/sys/util.h>
#include <zephyr/kernel.h>
#include "heap.h"

/* White-box sys_heap validation code.  Uses internal data structures.
 * Not expected to be useful in production apps.  This checks every
 * header field of every chunk and returns true if the totality of the
 * data structure is a valid heap.  It doesn't necessarily tell you
 * that it is the CORRECT heap given the history of alloc/free calls
 * that it can't inspect.  In a pathological case, you can imagine
 * something scribbling a copy of a previously-valid heap on top of a
 * running one and corrupting it. YMMV.
 */

#define VALIDATE(cond) do { if (!(cond)) { return false; } } while (0)

static bool in_bounds(struct z_heap *h, chunkid_t c)
{
	VALIDATE(c >= right_chunk(h, 0));
	VALIDATE(c < h->end_chunk);
	VALIDATE(chunk_size(h, c) < h->end_chunk);
	return true;
}

static bool valid_chunk(struct z_heap *h, chunkid_t c)
{
	VALIDATE(chunk_size(h, c) > 0);
	VALIDATE(c + chunk_size(h, c) <= h->end_chunk);
	VALIDATE(in_bounds(h, c));
	VALIDATE(right_chunk(h, left_chunk(h, c)) == c);
	VALIDATE(left_chunk(h, right_chunk(h, c)) == c);
	if (chunk_used(h, c)) {
		VALIDATE(!solo_free_header(h, c));
	} else {
		VALIDATE(chunk_used(h, left_chunk(h, c)));
		VALIDATE(chunk_used(h, right_chunk(h, c)));
		if (!solo_free_header(h, c)) {
			VALIDATE(in_bounds(h, prev_free_chunk(h, c)));
			VALIDATE(in_bounds(h, next_free_chunk(h, c)));
		}
	}
	return true;
}

/* Validate multiple state dimensions for the bucket "next" pointer
 * and see that they match.  Probably should unify the design a
 * bit...
 */
static inline void check_nexts(struct z_heap *h, int bidx)
{
	struct z_heap_bucket *b = &h->buckets[bidx];

	bool emptybit = (h->avail_buckets & BIT(bidx)) == 0;
	bool emptylist = b->next == 0;
	bool empties_match = emptybit == emptylist;

	(void)empties_match;
	CHECK(empties_match);

	if (b->next != 0) {
		CHECK(valid_chunk(h, b->next));
	}
}

bool sys_heap_validate(struct sys_heap *heap)
{
	struct z_heap *h = heap->heap;
	chunkid_t c;

	/*
	 * Walk through the chunks linearly, verifying sizes and end pointer.
	 */
	for (c = right_chunk(h, 0); c < h->end_chunk; c = right_chunk(h, c)) {
		if (!valid_chunk(h, c)) {
			return false;
		}
	}
	if (c != h->end_chunk) {
		return false;  /* Should have exactly consumed the buffer */
	}

#ifdef CONFIG_SYS_HEAP_RUNTIME_STATS
	/*
	 * Validate sys_heap_runtime_stats_get API.
	 * Iterate all chunks in sys_heap to get total allocated bytes and
	 * free bytes, then compare with the results of
	 * sys_heap_runtime_stats_get function.
	 */
	size_t allocated_bytes, free_bytes;
	struct sys_memory_stats stat;

	get_alloc_info(h, &allocated_bytes, &free_bytes);
	sys_heap_runtime_stats_get(heap, &stat);
	if ((stat.allocated_bytes != allocated_bytes) ||
	    (stat.free_bytes != free_bytes)) {
		return false;
	}
#endif

	/* Check the free lists: entry count should match, empty bit
	 * should be correct, and all chunk entries should point into
	 * valid unused chunks.  Mark those chunks USED, temporarily.
	 */
	for (int b = 0; b <= bucket_idx(h, h->end_chunk); b++) {
		chunkid_t c0 = h->buckets[b].next;
		uint32_t n = 0;

		check_nexts(h, b);

		for (c = c0; c != 0 && (n == 0 || c != c0);
		     n++, c = next_free_chunk(h, c)) {
			if (!valid_chunk(h, c)) {
				return false;
			}
			set_chunk_used(h, c, true);
		}

		bool empty = (h->avail_buckets & BIT(b)) == 0;
		bool zero = n == 0;

		if (empty != zero) {
			return false;
		}

		if (empty && h->buckets[b].next != 0) {
			return false;
		}
	}

	/*
	 * Walk through the chunks linearly again, verifying that all chunks
	 * but solo headers are now USED (i.e. all free blocks were found
	 * during enumeration).  Mark all such blocks UNUSED and solo headers
	 * USED.
	 */
	chunkid_t prev_chunk = 0;

	for (c = right_chunk(h, 0); c < h->end_chunk; c = right_chunk(h, c)) {
		if (!chunk_used(h, c) && !solo_free_header(h, c)) {
			return false;
		}
		if (left_chunk(h, c) != prev_chunk) {
			return false;
		}
		prev_chunk = c;

		set_chunk_used(h, c, solo_free_header(h, c));
	}
	if (c != h->end_chunk) {
		return false;  /* Should have exactly consumed the buffer */
	}

	/* Go through the free lists again checking that the linear
	 * pass caught all the blocks and that they now show UNUSED.
	 * Mark them USED.
	 */
	for (int b = 0; b <= bucket_idx(h, h->end_chunk); b++) {
		chunkid_t c0 = h->buckets[b].next;
		int n = 0;

		if (c0 == 0) {
			continue;
		}

		for (c = c0; n == 0 || c != c0; n++, c = next_free_chunk(h, c)) {
			if (chunk_used(h, c)) {
				return false;
			}
			set_chunk_used(h, c, true);
		}
	}

	/* Now we are valid, but have managed to invert all the in-use
	 * fields.  One more linear pass to fix them up
	 */
	for (c = right_chunk(h, 0); c < h->end_chunk; c = right_chunk(h, c)) {
		set_chunk_used(h, c, !chunk_used(h, c));
	}
	return true;
}
