// NOLINTNEXTLINE(bugprone-reserved-identifier,cert-dcl37-c,cert-dcl51-cpp)
#define _GNU_SOURCE
#include "libpldm/instance-id.h"
#include "libpldm/pldm.h"
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>

#define BIT(i) (1UL << (i))

#define PLDM_TID_MAX	 256
#define PLDM_INST_ID_MAX 32

/* We need to track our allocations explicitly due to OFD lock merging/splitting
 */
struct pldm_tid_state {
	pldm_instance_id_t prev;
	uint32_t allocations;
};

struct pldm_instance_db {
	struct pldm_tid_state state[PLDM_TID_MAX];
	int lock_db_fd;
};

static inline int iid_next(pldm_instance_id_t cur)
{
	return (cur + 1) % PLDM_INST_ID_MAX;
}

LIBPLDM_ABI_STABLE
int pldm_instance_db_init(struct pldm_instance_db **ctx, const char *dbpath)
{
	struct pldm_instance_db *l_ctx;
	struct stat statbuf;
	int rc;

	/* Make sure the provided pointer was initialised to NULL. In the future
	 * if we stabilise the ABI and expose the struct definition the caller
	 * can potentially pass a valid pointer to a struct they've allocated
	 */
	if (!ctx || *ctx) {
		return -EINVAL;
	}

	/* Ensure the underlying file is sized for properly managing allocations
	 */
	rc = stat(dbpath, &statbuf);
	if (rc < 0) {
		return -EINVAL;
	}

	if (statbuf.st_size <
	    ((off_t)(PLDM_TID_MAX) * (off_t)(PLDM_INST_ID_MAX))) {
		return -EINVAL;
	}

	l_ctx = calloc(1, sizeof(struct pldm_instance_db));
	if (!l_ctx) {
		return -ENOMEM;
	}

	/* Initialise previous ID values so the next one is zero */
	for (int i = 0; i < PLDM_TID_MAX; i++) {
		l_ctx->state[i].prev = 31;
	}

	/* Lock database may be read-only, either by permissions or mountpoint
	 */
	l_ctx->lock_db_fd = open(dbpath, O_RDONLY | O_CLOEXEC);
	if (l_ctx->lock_db_fd < 0) {
		free(l_ctx);
		return -errno;
	}
	*ctx = l_ctx;

	return 0;
}

LIBPLDM_ABI_STABLE
int pldm_instance_db_init_default(struct pldm_instance_db **ctx)
{
	return pldm_instance_db_init(ctx,
				     "/usr/share/libpldm/instance-db/default");
}

LIBPLDM_ABI_STABLE
int pldm_instance_db_destroy(struct pldm_instance_db *ctx)
{
	if (!ctx) {
		return 0;
	}
	close(ctx->lock_db_fd);
	free(ctx);
	return 0;
}

LIBPLDM_ABI_STABLE
int pldm_instance_id_alloc(struct pldm_instance_db *ctx, pldm_tid_t tid,
			   pldm_instance_id_t *iid)
{
	static const struct flock cfls = {
		.l_type = F_RDLCK,
		.l_whence = SEEK_SET,
		.l_len = 1,
	};
	static const struct flock cflx = {
		.l_type = F_WRLCK,
		.l_whence = SEEK_SET,
		.l_len = 1,
	};
	uint8_t l_iid;

	if (!iid) {
		return -EINVAL;
	}

	l_iid = ctx->state[tid].prev;
	if (l_iid >= PLDM_INST_ID_MAX) {
		return -EPROTO;
	}

	while ((l_iid = iid_next(l_iid)) != ctx->state[tid].prev) {
		struct flock flop;
		off_t loff;
		int rc;

		/* Have we already allocated this instance ID? */
		if (ctx->state[tid].allocations & BIT(l_iid)) {
			continue;
		}

		/* Derive the instance ID offset in the lock database */
		loff = tid * PLDM_INST_ID_MAX + l_iid;

		/* Reserving the TID's IID. Done via a shared lock */
		flop = cfls;
		flop.l_start = loff;
		rc = fcntl(ctx->lock_db_fd, F_OFD_SETLK, &flop);
		if (rc < 0) {
			if (errno == EAGAIN || errno == EINTR) {
				return -EAGAIN;
			}
			return -EPROTO;
		}

		/*
		 * If we *may* promote the lock to exclusive then this IID is
		 * only reserved by us. This is now our allocated IID.
		 *
		 * If we *may not* promote the lock to exclusive then this IID
		 * is also reserved on another file descriptor. Move on to the
		 * next IID index.
		 *
		 * Note that we cannot actually *perform* the promotion in
		 * practice because this is prevented by the lock database being
		 * opened O_RDONLY.
		 */
		flop = cflx;
		flop.l_start = loff;
		rc = fcntl(ctx->lock_db_fd, F_OFD_GETLK, &flop);
		if (rc < 0) {
			if (errno == EAGAIN || errno == EINTR) {
				return -EAGAIN;
			}
			return -EPROTO;
		}

		/* F_UNLCK is the type of the lock if we could successfully
		 * promote it to F_WRLCK */
		if (flop.l_type == F_UNLCK) {
			ctx->state[tid].prev = l_iid;
			ctx->state[tid].allocations |= BIT(l_iid);
			*iid = l_iid;
			return 0;
		}
		if (flop.l_type != F_RDLCK) {
			return -EPROTO;
		}
	}

	/* Failed to allocate an IID after a full loop. Make the caller try
	 * again */
	return -EAGAIN;
}

LIBPLDM_ABI_STABLE
int pldm_instance_id_free(struct pldm_instance_db *ctx, pldm_tid_t tid,
			  pldm_instance_id_t iid)
{
	static const struct flock cflu = {
		.l_type = F_UNLCK,
		.l_whence = SEEK_SET,
		.l_len = 1,
	};
	struct flock flop;
	int rc;

	/* Trying to free an instance ID that is not currently allocated */
	if (!(ctx->state[tid].allocations & BIT(iid))) {
		return -EINVAL;
	}

	flop = cflu;
	flop.l_start = tid * PLDM_INST_ID_MAX + iid;
	rc = fcntl(ctx->lock_db_fd, F_OFD_SETLK, &flop);
	if (rc < 0) {
		if (errno == EAGAIN || errno == EINTR) {
			return -EAGAIN;
		}
		return -EPROTO;
	}

	/* Mark the instance ID as no-longer allocated */
	ctx->state[tid].allocations &= ~BIT(iid);

	return 0;
}
