#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;

	handle = NULL;
	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;
}
