/* Copyright (C) 2017 Mellanox Technologies Inc */

struct semanage_ibendport;
struct semanage_ibendport_key;
typedef struct semanage_ibendport_key record_key_t;
typedef struct semanage_ibendport record_t;
#define DBASE_RECORD_DEFINED

#include <stdlib.h>
#include <string.h>
#include <sepol/policydb.h>
#include "ibendport_internal.h"
#include "debug.h"
#include "handle.h"
#include "database.h"

int semanage_ibendport_modify_local(semanage_handle_t *handle,
				    const semanage_ibendport_key_t *key,
				    const semanage_ibendport_t *data)
{
	dbase_config_t *dconfig = semanage_ibendport_dbase_local(handle);

	return dbase_modify(handle, dconfig, key, data);
}

int semanage_ibendport_del_local(semanage_handle_t *handle,
				 const semanage_ibendport_key_t *key)
{
	dbase_config_t *dconfig = semanage_ibendport_dbase_local(handle);

	return dbase_del(handle, dconfig, key);
}

int semanage_ibendport_query_local(semanage_handle_t *handle,
				   const semanage_ibendport_key_t *key,
				   semanage_ibendport_t **response)
{
	dbase_config_t *dconfig = semanage_ibendport_dbase_local(handle);

	return dbase_query(handle, dconfig, key, response);
}

int semanage_ibendport_exists_local(semanage_handle_t *handle,
				    const semanage_ibendport_key_t *key,
				    int *response)
{
	dbase_config_t *dconfig = semanage_ibendport_dbase_local(handle);

	return dbase_exists(handle, dconfig, key, response);
}

int semanage_ibendport_count_local(semanage_handle_t *handle,
				   unsigned int *response)
{
	dbase_config_t *dconfig = semanage_ibendport_dbase_local(handle);

	return dbase_count(handle, dconfig, response);
}

int semanage_ibendport_iterate_local(semanage_handle_t *handle,
				     int (*handler)(const semanage_ibendport_t *record,
						    void *varg), void *handler_arg)
{
	dbase_config_t *dconfig = semanage_ibendport_dbase_local(handle);
	return dbase_iterate(handle, dconfig, handler, handler_arg);
}

int semanage_ibendport_list_local(semanage_handle_t *handle,
				  semanage_ibendport_t ***records,
				  unsigned int *count)
{
	dbase_config_t *dconfig = semanage_ibendport_dbase_local(handle);

	return dbase_list(handle, dconfig, records, count);
}

hidden_def(semanage_ibendport_list_local)

int hidden semanage_ibendport_validate_local(semanage_handle_t *handle)
{
	semanage_ibendport_t **ibendports = NULL;
	unsigned int nibendports = 0;
	unsigned int i = 0, j = 0;
	char *ibdev_name;
	char *ibdev_name2;
	int port;
	int port2;

	/* List and sort the ibendports */
	if (semanage_ibendport_list_local(handle, &ibendports, &nibendports) < 0)
		goto err;

	qsort(ibendports, nibendports, sizeof(semanage_ibendport_t *),
	      (int (*)(const void *, const void *))
	      &semanage_ibendport_compare2_qsort);

	/* Test each ibendport */
	while (i < nibendports) {
		int stop = 0;

		if (STATUS_SUCCESS !=
				semanage_ibendport_get_ibdev_name(handle,
								  ibendports[i],
								  &ibdev_name)) {
			ERR(handle, "Couldn't get IB device name");
			goto err;
		}

		port = semanage_ibendport_get_port(ibendports[i]);

		/* Find the first ibendport with matching
		 * ibdev_name to compare against
		 */
		do {
			if (j == nibendports - 1)
				goto next;
			j++;
			if (STATUS_SUCCESS !=
				semanage_ibendport_get_ibdev_name(handle,
								  ibendports[j],
								  &ibdev_name2)) {
				ERR(handle, "Couldn't get IB device name.");
				goto err;
			}
			port2 = semanage_ibendport_get_port(ibendports[j]);

			stop = !strcmp(ibdev_name, ibdev_name2);
		} while (!stop);

		if (port == port2) {
			ERR(handle, "ibendport %s/%u already exists.",
			    ibdev_name2, port2);
			goto invalid;
		}
next:
		i++;
		j = i;
	}

	for (i = 0; i < nibendports; i++)
		semanage_ibendport_free(ibendports[i]);
	free(ibendports);
	return STATUS_SUCCESS;

err:
	ERR(handle, "could not complete ibendports validity check");

invalid:
	for (i = 0; i < nibendports; i++)
		semanage_ibendport_free(ibendports[i]);
	free(ibendports);
	return STATUS_ERR;
}
