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

#include "user_internal.h"
#include "debug.h"

struct sepol_user {
	/* This user's name */
	char *name;

	/* This user's mls level (only required for mls) */
	char *mls_level;

	/* This user's mls range (only required for mls) */
	char *mls_range;

	/* The role array */
	char **roles;

	/* The number of roles */
	unsigned int num_roles;
};

struct sepol_user_key {
	/* This user's name */
	const char *name;
};

int sepol_user_key_create(sepol_handle_t * handle,
			  const char *name, sepol_user_key_t ** key_ptr)
{

	sepol_user_key_t *tmp_key =
	    (sepol_user_key_t *) malloc(sizeof(sepol_user_key_t));

	if (!tmp_key) {
		ERR(handle, "out of memory, "
		    "could not create selinux user key");
		return STATUS_ERR;
	}

	tmp_key->name = name;

	*key_ptr = tmp_key;
	return STATUS_SUCCESS;
}

hidden_def(sepol_user_key_create)

void sepol_user_key_unpack(const sepol_user_key_t * key, const char **name)
{

	*name = key->name;
}

hidden_def(sepol_user_key_unpack)

int sepol_user_key_extract(sepol_handle_t * handle,
			   const sepol_user_t * user,
			   sepol_user_key_t ** key_ptr)
{

	if (sepol_user_key_create(handle, user->name, key_ptr) < 0) {
		ERR(handle, "could not extract key from user %s", user->name);
		return STATUS_ERR;
	}

	return STATUS_SUCCESS;
}

void sepol_user_key_free(sepol_user_key_t * key)
{
	free(key);
}

int sepol_user_compare(const sepol_user_t * user, const sepol_user_key_t * key)
{

	return strcmp(user->name, key->name);
}

int sepol_user_compare2(const sepol_user_t * user, const sepol_user_t * user2)
{

	return strcmp(user->name, user2->name);
}

/* Name */
const char *sepol_user_get_name(const sepol_user_t * user)
{

	return user->name;
}

int sepol_user_set_name(sepol_handle_t * handle,
			sepol_user_t * user, const char *name)
{

	char *tmp_name = strdup(name);
	if (!tmp_name) {
		ERR(handle, "out of memory, could not set name");
		return STATUS_ERR;
	}
	free(user->name);
	user->name = tmp_name;
	return STATUS_SUCCESS;
}

hidden_def(sepol_user_set_name)

/* MLS */
const char *sepol_user_get_mlslevel(const sepol_user_t * user)
{

	return user->mls_level;
}

hidden_def(sepol_user_get_mlslevel)

int sepol_user_set_mlslevel(sepol_handle_t * handle,
			    sepol_user_t * user, const char *mls_level)
{

	char *tmp_mls_level = strdup(mls_level);
	if (!tmp_mls_level) {
		ERR(handle, "out of memory, "
		    "could not set MLS default level");
		return STATUS_ERR;
	}
	free(user->mls_level);
	user->mls_level = tmp_mls_level;
	return STATUS_SUCCESS;
}

hidden_def(sepol_user_set_mlslevel)

const char *sepol_user_get_mlsrange(const sepol_user_t * user)
{

	return user->mls_range;
}

hidden_def(sepol_user_get_mlsrange)

int sepol_user_set_mlsrange(sepol_handle_t * handle,
			    sepol_user_t * user, const char *mls_range)
{

	char *tmp_mls_range = strdup(mls_range);
	if (!tmp_mls_range) {
		ERR(handle, "out of memory, "
		    "could not set MLS allowed range");
		return STATUS_ERR;
	}
	free(user->mls_range);
	user->mls_range = tmp_mls_range;
	return STATUS_SUCCESS;
}

hidden_def(sepol_user_set_mlsrange)

/* Roles */
int sepol_user_get_num_roles(const sepol_user_t * user)
{

	return user->num_roles;
}

int sepol_user_add_role(sepol_handle_t * handle,
			sepol_user_t * user, const char *role)
{

	char *role_cp;
	char **roles_realloc;

	if (sepol_user_has_role(user, role))
		return STATUS_SUCCESS;

	role_cp = strdup(role);
	roles_realloc = realloc(user->roles,
				sizeof(char *) * (user->num_roles + 1));

	if (!role_cp || !roles_realloc)
		goto omem;

	user->num_roles++;
	user->roles = roles_realloc;
	user->roles[user->num_roles - 1] = role_cp;

	return STATUS_SUCCESS;

      omem:
	ERR(handle, "out of memory, could not add role %s", role);
	free(role_cp);
	free(roles_realloc);
	return STATUS_ERR;
}

hidden_def(sepol_user_add_role)

int sepol_user_has_role(const sepol_user_t * user, const char *role)
{

	unsigned int i;

	for (i = 0; i < user->num_roles; i++)
		if (!strcmp(user->roles[i], role))
			return 1;
	return 0;
}

hidden_def(sepol_user_has_role)

int sepol_user_set_roles(sepol_handle_t * handle,
			 sepol_user_t * user,
			 const char **roles_arr, unsigned int num_roles)
{

	unsigned int i;
	char **tmp_roles = NULL;

	if (num_roles > 0) {

		/* First, make a copy */
		tmp_roles = (char **)calloc(1, sizeof(char *) * num_roles);
		if (!tmp_roles)
			goto omem;

		for (i = 0; i < num_roles; i++) {
			tmp_roles[i] = strdup(roles_arr[i]);
			if (!tmp_roles[i])
				goto omem;
		}
	}

	/* Apply other changes */
	for (i = 0; i < user->num_roles; i++)
		free(user->roles[i]);
	free(user->roles);
	user->roles = tmp_roles;
	user->num_roles = num_roles;
	return STATUS_SUCCESS;

      omem:
	ERR(handle, "out of memory, could not allocate roles array for"
	    "user %s", user->name);

	if (tmp_roles) {
		for (i = 0; i < num_roles; i++) {
			if (!tmp_roles[i])
				break;
			free(tmp_roles[i]);
		}
	}
	free(tmp_roles);
	return STATUS_ERR;
}

int sepol_user_get_roles(sepol_handle_t * handle,
			 const sepol_user_t * user,
			 const char ***roles_arr, unsigned int *num_roles)
{

	unsigned int i;
	const char **tmp_roles =
	    (const char **)malloc(sizeof(char *) * user->num_roles);
	if (!tmp_roles)
		goto omem;

	for (i = 0; i < user->num_roles; i++)
		tmp_roles[i] = user->roles[i];

	*roles_arr = tmp_roles;
	*num_roles = user->num_roles;
	return STATUS_SUCCESS;

      omem:
	ERR(handle, "out of memory, could not "
	    "allocate roles array for user %s", user->name);
	free(tmp_roles);
	return STATUS_ERR;
}

hidden_def(sepol_user_get_roles)

void sepol_user_del_role(sepol_user_t * user, const char *role)
{

	unsigned int i;
	for (i = 0; i < user->num_roles; i++) {
		if (!strcmp(user->roles[i], role)) {
			free(user->roles[i]);
			user->roles[i] = NULL;
			user->roles[i] = user->roles[user->num_roles - 1];
			user->num_roles--;
		}
	}
}

/* Create */
int sepol_user_create(sepol_handle_t * handle, sepol_user_t ** user_ptr)
{

	sepol_user_t *user = (sepol_user_t *) malloc(sizeof(sepol_user_t));

	if (!user) {
		ERR(handle, "out of memory, "
		    "could not create selinux user record");
		return STATUS_ERR;
	}

	user->roles = NULL;
	user->num_roles = 0;
	user->name = NULL;
	user->mls_level = NULL;
	user->mls_range = NULL;

	*user_ptr = user;
	return STATUS_SUCCESS;
}

hidden_def(sepol_user_create)

/* Deep copy clone */
int sepol_user_clone(sepol_handle_t * handle,
		     const sepol_user_t * user, sepol_user_t ** user_ptr)
{

	sepol_user_t *new_user = NULL;
	unsigned int i;

	if (sepol_user_create(handle, &new_user) < 0)
		goto err;

	if (sepol_user_set_name(handle, new_user, user->name) < 0)
		goto err;

	for (i = 0; i < user->num_roles; i++) {
		if (sepol_user_add_role(handle, new_user, user->roles[i]) < 0)
			goto err;
	}

	if (user->mls_level &&
	    (sepol_user_set_mlslevel(handle, new_user, user->mls_level) < 0))
		goto err;

	if (user->mls_range &&
	    (sepol_user_set_mlsrange(handle, new_user, user->mls_range) < 0))
		goto err;

	*user_ptr = new_user;
	return STATUS_SUCCESS;

      err:
	ERR(handle, "could not clone selinux user record");
	sepol_user_free(new_user);
	return STATUS_ERR;
}

/* Destroy */
void sepol_user_free(sepol_user_t * user)
{

	unsigned int i;

	if (!user)
		return;

	free(user->name);
	for (i = 0; i < user->num_roles; i++)
		free(user->roles[i]);
	free(user->roles);
	free(user->mls_level);
	free(user->mls_range);
	free(user);
}

hidden_def(sepol_user_free)
