#include <string.h>
#include <stdlib.h>

#include "handle.h"
#include "private.h"
#include "debug.h"

#include <sepol/booleans.h>
#include <sepol/policydb/hashtab.h>
#include <sepol/policydb/policydb.h>
#include <sepol/policydb/conditional.h>
#include "boolean_internal.h"

static int bool_update(sepol_handle_t * handle,
		       policydb_t * policydb,
		       const sepol_bool_key_t * key, const sepol_bool_t * data)
{

	const char *cname;
	char *name;
	int value;

	sepol_bool_key_unpack(key, &cname);
	name = strdup(cname);
	value = sepol_bool_get_value(data);

	if (!name)
		goto omem;

	cond_bool_datum_t *datum =
	    hashtab_search(policydb->p_bools.table, name);
	if (!datum) {
		ERR(handle, "boolean %s no longer in policy", name);
		goto err;
	}
	if (value != 0 && value != 1) {
		ERR(handle, "illegal value %d for boolean %s", value, name);
		goto err;
	}

	free(name);
	datum->state = value;
	return STATUS_SUCCESS;

      omem:
	ERR(handle, "out of memory");

      err:
	free(name);
	ERR(handle, "could not update boolean %s", cname);
	return STATUS_ERR;
}

static int bool_to_record(sepol_handle_t * handle,
			  const policydb_t * policydb,
			  int bool_idx, sepol_bool_t ** record)
{

	const char *name = policydb->p_bool_val_to_name[bool_idx];
	cond_bool_datum_t *booldatum = policydb->bool_val_to_struct[bool_idx];
	int value = booldatum->state;

	sepol_bool_t *tmp_record = NULL;

	if (sepol_bool_create(handle, &tmp_record) < 0)
		goto err;

	if (sepol_bool_set_name(handle, tmp_record, name) < 0)
		goto err;

	sepol_bool_set_value(tmp_record, value);

	*record = tmp_record;
	return STATUS_SUCCESS;

      err:
	ERR(handle, "could not convert boolean %s to record", name);
	sepol_bool_free(tmp_record);
	return STATUS_ERR;
}

int sepol_bool_set(sepol_handle_t * handle,
		   sepol_policydb_t * p,
		   const sepol_bool_key_t * key, const sepol_bool_t * data)
{

	const char *name;
	sepol_bool_key_unpack(key, &name);

	policydb_t *policydb = &p->p;
	if (bool_update(handle, policydb, key, data) < 0)
		goto err;

	if (evaluate_conds(policydb) < 0) {
		ERR(handle, "error while re-evaluating conditionals");
		goto err;
	}

	return STATUS_SUCCESS;

      err:
	ERR(handle, "could not set boolean %s", name);
	return STATUS_ERR;
}

int sepol_bool_count(sepol_handle_t * handle __attribute__ ((unused)),
		     const sepol_policydb_t * p, unsigned int *response)
{

	const policydb_t *policydb = &p->p;
	*response = policydb->p_bools.nprim;

	return STATUS_SUCCESS;
}

int sepol_bool_exists(sepol_handle_t * handle,
		      const sepol_policydb_t * p,
		      const sepol_bool_key_t * key, int *response)
{

	const policydb_t *policydb = &p->p;

	const char *cname;
	char *name = NULL;
	sepol_bool_key_unpack(key, &cname);
	name = strdup(cname);

	if (!name) {
		ERR(handle, "out of memory, could not check "
		    "if user %s exists", cname);
		return STATUS_ERR;
	}

	*response = (hashtab_search(policydb->p_bools.table, name) != NULL);
	free(name);
	return STATUS_SUCCESS;
}

int sepol_bool_query(sepol_handle_t * handle,
		     const sepol_policydb_t * p,
		     const sepol_bool_key_t * key, sepol_bool_t ** response)
{

	const policydb_t *policydb = &p->p;
	cond_bool_datum_t *booldatum = NULL;

	const char *cname;
	char *name = NULL;
	sepol_bool_key_unpack(key, &cname);
	name = strdup(cname);

	if (!name)
		goto omem;

	booldatum = hashtab_search(policydb->p_bools.table, name);
	if (!booldatum) {
		*response = NULL;
		return STATUS_SUCCESS;
	}

	if (bool_to_record(handle, policydb,
			   booldatum->s.value - 1, response) < 0)
		goto err;

	free(name);
	return STATUS_SUCCESS;

      omem:
	ERR(handle, "out of memory");

      err:
	ERR(handle, "could not query boolean %s", cname);
	free(name);
	return STATUS_ERR;
}

int sepol_bool_iterate(sepol_handle_t * handle,
		       const sepol_policydb_t * p,
		       int (*fn) (const sepol_bool_t * boolean,
				  void *fn_arg), void *arg)
{

	const policydb_t *policydb = &p->p;
	unsigned int nbools = policydb->p_bools.nprim;
	sepol_bool_t *boolean = NULL;
	unsigned int i;

	/* For each boolean */
	for (i = 0; i < nbools; i++) {

		int status;

		if (bool_to_record(handle, policydb, i, &boolean) < 0)
			goto err;

		/* Invoke handler */
		status = fn(boolean, arg);
		if (status < 0)
			goto err;

		sepol_bool_free(boolean);
		boolean = NULL;

		/* Handler requested exit */
		if (status > 0)
			break;
	}

	return STATUS_SUCCESS;

      err:
	ERR(handle, "could not iterate over booleans");
	sepol_bool_free(boolean);
	return STATUS_ERR;
}
