/****************************************************************************\
 *  resource_functions.c - functions dealing with resources in the
 *                        accounting system.
 *****************************************************************************
 *  Copyright (C) 2013 Bull S. A. S.
 *		Bull, Rue Jean Jaures, B.P.68, 78340, Les Clayes-sous-Bois.
 *
 *  Written by Bill Brophy <bill.brophy@bull.com>
 *
 *  This file is part of Slurm, a resource management program.
 *  For details, see <https://slurm.schedmd.com>.
 *  Please also read the included file: DISCLAIMER.
 *
 *  Slurm is free software; you can redistribute it and/or modify it under
 *  the terms of the GNU General Public License as published by the Free
 *  Software Foundation; either version 2 of the License, or (at your option)
 *  any later version.
 *
 *  In addition, as a special exception, the copyright holders give permission
 *  to link the code of portions of this program with the OpenSSL library under
 *  certain conditions as described in each individual source file, and
 *  distribute linked combinations including the two. You must obey the GNU
 *  General Public License in all respects for all of the code used other than
 *  OpenSSL. If you modify file(s) with this exception, you may extend this
 *  exception to your version of the file(s), but you are not obligated to do
 *  so. If you do not wish to do so, delete this exception statement from your
 *  version.  If you delete this exception statement from all source files in
 *  the program, then also delete it here.
 *
 *  Slurm is distributed in the hope that it will be useful, but WITHOUT ANY
 *  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 *  FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 *  details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with Slurm; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA.
\****************************************************************************/

#include "src/sacctmgr/sacctmgr.h"

static void _print_overcommit(slurmdb_res_rec_t *res,
			      slurmdb_res_cond_t *res_cond)
{
	list_t *res_list = NULL, *cluster_list = NULL;
	list_itr_t *itr, *clus_itr = NULL, *found_clus_itr = NULL;
	slurmdb_res_rec_t *found_res;
	slurmdb_clus_res_rec_t *clus_res = NULL;
	char *cluster;

	if (res->allocated == NO_VAL)
		return;

	/* Don't use the global g_res_list since we are going to
	 * change the contents of this one.
	 */
	res_cond->with_clusters = 1;

	if (res_cond->cluster_list) {
		cluster_list = res_cond->cluster_list;
		res_cond->cluster_list = NULL;
	}

	res_list = slurmdb_res_get(db_conn, res_cond);
	if (!res_list) {
		exit_code=1;
		fprintf(stderr, " Problem getting system resources "
			"from database.  Contact your admin.\n");
		return;
	}

	itr = list_iterator_create(res_list);
	while ((found_res = list_next(itr))) {
		int total = 0, allowed;
		char *percent_str = "%";

		if (found_res->flags & SLURMDB_RES_FLAG_ABSOLUTE)
			percent_str = "";

		fprintf(stderr, "  %s@%s\n",
			found_res->name, found_res->server);
		if (cluster_list)
			clus_itr = list_iterator_create(cluster_list);
		if (found_res->clus_res_list) {
			found_clus_itr = list_iterator_create(
				found_res->clus_res_list);
			while ((clus_res = list_next(found_clus_itr))) {
				cluster = NULL;
				if (clus_itr) {
					while ((cluster = list_next(clus_itr)))
						if (!xstrcmp(cluster,
							     clus_res->cluster))
						    break;
					list_iterator_reset(clus_itr);
				} else {
					/*
					 * This means we didn't specify any
					 * clusters (All clusters are
					 * overwritten with the requested
					 * percentage/count) so just put
					 * something there to get the correct
					 * allowed.
					 */
					cluster = "nothing";
				}
				allowed = cluster ? res->allocated :
					clus_res->allowed;
				total += allowed;

				fprintf(stderr,
					"   Cluster - %s\t %u%s\n",
					clus_res->cluster,
					allowed, percent_str);
			}
		} else if (clus_itr) {
			while ((cluster = list_next(clus_itr))) {
				total += res->allocated;
				fprintf(stderr,
					"   Cluster - %s\t %u%s\n",
					cluster, res->allocated,
					percent_str);
			}
		}
		if (clus_itr)
			list_iterator_destroy(clus_itr);
		if (found_clus_itr)
			list_iterator_destroy(found_clus_itr);
		fprintf(stderr, "   total\t\t%u%s\n", total, percent_str);
	}
	list_iterator_destroy(itr);

	if (cluster_list) {
		res_cond->cluster_list = cluster_list;
		cluster_list = NULL;
	}
}

static int _set_res_cond(int *start, int argc, char **argv,
			 slurmdb_res_cond_t *res_cond,
			 list_t *format_list)
{
	int i;
	int set = 0;
	int end = 0;
	int command_len = 0;

	if (!res_cond) {
		error("No res_cond given");
		return -1;
	}

	for (i=(*start); i<argc; i++) {
		int op_type;
		end = parse_option_end(argv[i], &op_type, &command_len);
		if (!common_verify_option_syntax(argv[i], op_type, false))
			continue;

		if (!xstrncasecmp(argv[i], "Set", MAX(command_len, 3))) {
			i--;
			break;
		} else if (!end && !xstrncasecmp(argv[i], "WithDeleted",
						 MAX(command_len, 5))) {
			res_cond->with_deleted = 1;
		} else if (!end && !xstrncasecmp(argv[i], "WithClusters",
						 MAX(command_len, 5))) {
			res_cond->with_clusters = 1;
		} else if (!end && !xstrncasecmp(argv[i], "where",
						 MAX(command_len, 5))) {
			continue;
		} else if (!end
			   || !xstrncasecmp(argv[i], "Names",
					    MAX(command_len, 1))) {
			if (!res_cond->name_list) {
				res_cond->name_list = list_create(xfree_ptr);
			}
			if (slurm_addto_char_list(res_cond->name_list,
						  argv[i]+end))
				set = 1;
		} else if (!end
			   || !xstrncasecmp(argv[i], "Clusters",
					    MAX(command_len, 1))) {
			if (!res_cond->cluster_list) {
				res_cond->cluster_list = list_create(xfree_ptr);
			}

			slurm_addto_char_list(res_cond->cluster_list,
					      argv[i]+end);
			if (sacctmgr_validate_cluster_list(
				    res_cond->cluster_list) != SLURM_SUCCESS) {
				exit_code=1;
				fprintf(stderr,
					" Need a valid cluster name to "
					"add a cluster resource.\n");
			} else
				set = 1;
		} else if (!xstrncasecmp(argv[i], "Descriptions",
					 MAX(command_len, 1))) {
			if (!res_cond->description_list) {
				res_cond->description_list =
					list_create(xfree_ptr);
			}
			if (slurm_addto_char_list(
				    res_cond->description_list,
				    argv[i]+end))
				set = 1;
		} else if (!xstrncasecmp(argv[i], "Format",
					 MAX(command_len, 1))) {
			if (format_list)
				slurm_addto_char_list(format_list, argv[i]+end);
		} else if (!xstrncasecmp(argv[i], "Ids", MAX(command_len, 1))) {
			list_itr_t *itr = NULL;
			char *temp = NULL;
			uint32_t id = 0;

			if (!res_cond->id_list) {
				res_cond->id_list = list_create(xfree_ptr);
			}
			if (slurm_addto_char_list(res_cond->id_list,
						  argv[i]+end))
				set = 1;

			/* check to make sure user gave ints here */
			itr = list_iterator_create(res_cond->id_list);
			while ((temp = list_next(itr))) {
				if (get_uint(temp, &id, "RES ID")
				    != SLURM_SUCCESS) {
					exit_code = 1;
					list_delete_item(itr);
				}
			}
			list_iterator_destroy(itr);
		} else if (!xstrncasecmp(argv[i], "Allowed",
					 MAX(command_len, 1)) ||
			   !xstrncasecmp(argv[i], "PercentAllowed",
					 MAX(command_len, 1))) {
			if (!res_cond->allowed_list)
				res_cond->allowed_list = list_create(xfree_ptr);
			if (slurm_addto_char_list(res_cond->allowed_list,
						  argv[i]+end))
				set = 1;
		} else if (!xstrncasecmp(argv[i], "ServerType",
					 MAX(command_len, 7))) {
			if (!res_cond->manager_list) {
				res_cond->manager_list = list_create(xfree_ptr);
			}
			if (slurm_addto_char_list(res_cond->manager_list,
						  argv[i]+end))
				set = 1;
		} else if (!xstrncasecmp(argv[i], "Server",
					 MAX(command_len, 2))) {
			if (!res_cond->server_list) {
				res_cond->server_list = list_create(xfree_ptr);
			}
			if (slurm_addto_char_list(res_cond->server_list,
						  argv[i]+end))
				set = 1;
		} else {
			exit_code=1;
			fprintf(stderr, " Unknown condition: %s\n"
				" Use keyword 'set' to modify "
				"SLURM_PRINT_VALUE\n", argv[i]);
		}
	}

	(*start) = i;
	return set;
}

static int _set_res_rec(int *start, int argc, char **argv,
			list_t *name_list, list_t *cluster_list,
			slurmdb_res_rec_t *res)
{
	int i;
	int set = 0;
	int end = 0;
	int command_len = 0;
	int option = 0;
	bool allow_option = false;

	xassert(res);

	for (i=(*start); i<argc; i++) {
		end = parse_option_end(argv[i], &option, &command_len);

		if (!xstrncasecmp(argv[i], "Where", MAX(command_len, 5))) {
			i--;
			break;
		} else if (!end && !xstrncasecmp(argv[i], "set",
						 MAX(command_len, 3))) {
			continue;
		} else if (!end
			   || !xstrncasecmp(argv[i], "Names",
					    MAX(command_len, 1))
			   || !xstrncasecmp(argv[i], "Resources",
					    MAX(command_len, 1))) {
			if (name_list)
				slurm_addto_char_list(name_list, argv[i]+end);
		} else if (!xstrncasecmp(argv[i], "Clusters",
					 MAX(command_len, 1))) {
			if (cluster_list) {
				slurm_addto_char_list(cluster_list,
						      argv[i]+end);
				if (sacctmgr_validate_cluster_list(
					    cluster_list) != SLURM_SUCCESS) {
					exit_code=1;
					fprintf(stderr,
						" Need a valid cluster name to "
						"add a cluster resource.\n");
				}
			} else {
				exit_code=1;
				fprintf(stderr,
					" Can't modify the cluster "
					"of an resource\n");
			}
		} else if (!xstrncasecmp(argv[i], "Count",
					 MAX(command_len, 3))) {
			if (get_uint(argv[i]+end, &res->count,
				     "count") == SLURM_SUCCESS) {
				set = 1;
			}
		} else if (!xstrncasecmp(argv[i], "Description",
					 MAX(command_len, 1))) {
			if (!res->description)
				res->description =
					strip_quotes(argv[i]+end, NULL, 1);
			set = 1;
		} else if (!xstrncasecmp(argv[i], "Flags",
					 MAX(command_len, 2))) {
			allow_option = true;
			res->flags = str_2_res_flags(argv[i]+end, option);
			if (res->flags == SLURMDB_RES_FLAG_NOTSET) {
				char *tmp_char = slurmdb_res_flags_str(
					SLURMDB_RES_FLAG_BASE);
				printf(" Unknown Server Resource flag used "
				       "in:\n  '%s'\n"
				       " Valid Server Resource flags are\n"
				       " '%s'\n", argv[i]+end, tmp_char);
				xfree(tmp_char);
				exit_code = 1;
			} else
				set = 1;

		} else if (!xstrncasecmp(argv[i], "Server",
					MAX(command_len, 1))) {
			if (!res->server) {
				res->server=
					strip_quotes(argv[i]+end, NULL, 1);
			}
			set = 1;
		} else if (!xstrncasecmp(argv[i], "ServerType",
					 MAX(command_len, 1))) {
			if (!res->manager)
				res->manager =
					strip_quotes(argv[i]+end, NULL, 1);
			set = 1;
		} else if (!xstrncasecmp(argv[i], "Allowed",
					 MAX(command_len, 1)) ||
			   !xstrncasecmp(argv[i], "PercentAllowed",
					 MAX(command_len, 1))) {
			/* overload allocated here */
			if (get_uint(argv[i]+end, &res->allocated,
				     "Allowed") == SLURM_SUCCESS) {
				set = 1;
			}
		} else if (!xstrncasecmp(argv[i], "LastConsumed",
					 MAX(command_len, 8))) {
			if (get_uint(argv[i]+end, &res->last_consumed,
				     "LastConsumed") == SLURM_SUCCESS) {
				set = 1;
			}
		} else if (!xstrncasecmp(argv[i], "Type",
					 MAX(command_len, 1))) {
			char *temp = strip_quotes(argv[i]+end, NULL, 1);

			if (!xstrncasecmp("License", temp,
					  MAX(strlen(temp), 1))) {
				res->type = SLURMDB_RESOURCE_LICENSE;
			} else {
				exit_code = 1;
				fprintf(stderr,
					" Unknown resource type: '%s'  "
					"Valid resources is License.\n",
					temp);
			}
			xfree(temp);
		} else {
			allow_option = true;
			exit_code = 1;
			printf(" Unknown option: %s\n"
			       " Use keyword 'where' to modify condition\n",
			       argv[i]);
		}

		common_verify_option_syntax(argv[i], option, allow_option);
	}

	(*start) = i;

	return set;
}

static void _print_res_format(slurmdb_res_rec_t *res,
			      slurmdb_clus_res_rec_t *clus_res,
			      list_itr_t *itr,
			      int field_count)
{
	int curr_inx = 1;
	char *tmp_char;
	print_field_t *field = NULL;
	uint32_t tmp_uint32;

	xassert(itr);
	xassert(res);

	while ((field = list_next(itr))) {
		switch(field->type) {
		case PRINT_LAST_CONSUMED:
			field->print_routine(field, &res->last_consumed,
					     (curr_inx == field_count));
			break;
		case PRINT_ALLOWED:
			tmp_uint32 = clus_res ? clus_res->allowed : 0;
			field->print_routine(
				field, &tmp_uint32,
				(curr_inx == field_count));
			break;
		case PRINT_CLUSTER:
			tmp_char = clus_res ? clus_res->cluster : NULL;
			field->print_routine(
				field, tmp_char,
				(curr_inx == field_count));
			break;
		case PRINT_CALLOWED:
			if (clus_res) {
				if (res->flags & SLURMDB_RES_FLAG_ABSOLUTE)
					tmp_uint32 = res->count;
				else
					tmp_uint32 = (res->count *
						clus_res->allowed) / 100;
			} else
				tmp_uint32 = 0;
			field->print_routine(field, &tmp_uint32,
					     (curr_inx == field_count));
			break;
		case PRINT_COUNT:
			field->print_routine(field,
					     &res->count,
					     (curr_inx == field_count));
			break;
		case PRINT_DESC:
			field->print_routine(
				field, res->description,
				(curr_inx == field_count));
			break;
		case PRINT_ID:
			field->print_routine(
				field, &res->id,
				(curr_inx == field_count));
			break;
		case PRINT_FLAGS:
			tmp_char = slurmdb_res_flags_str(res->flags);
			field->print_routine(
				field,
				tmp_char,
				(curr_inx == field_count));
			xfree(tmp_char);
			break;
		case PRINT_SERVERTYPE:
			field->print_routine(field,
					     res->manager,
					     (curr_inx == field_count));
			break;
		case PRINT_NAME:
			field->print_routine(
				field, res->name,
				(curr_inx == field_count));
			break;
		case PRINT_SERVER:
			field->print_routine(field,
					     res->server,
					     (curr_inx == field_count));
			break;
		case PRINT_TYPE:
			tmp_char = slurmdb_res_type_str(res->type);
			field->print_routine(field,
					     tmp_char,
					     (curr_inx == field_count));
			tmp_char = NULL;
			break;
		case PRINT_ALLOCATED:
			field->print_routine(
				field, &res->allocated,
				(curr_inx == field_count));
			break;
		default:
			field->print_routine(
				field, NULL,
				(curr_inx == field_count));
			break;
		}
		curr_inx++;
	}
	list_iterator_reset(itr);
	printf("\n");
}

extern int sacctmgr_add_res(int argc, char **argv)

{
	int rc = SLURM_SUCCESS;
	int i = 0;
	list_itr_t *itr = NULL;
	list_itr_t *clus_itr = NULL;
	slurmdb_res_rec_t *res = NULL;
	slurmdb_res_rec_t *found_res = NULL;
	slurmdb_res_rec_t *start_res = xmalloc(sizeof(slurmdb_res_rec_t));
	list_t *cluster_list = list_create(xfree_ptr);
	list_t *name_list = list_create(xfree_ptr);
	char *name = NULL;
	list_t *res_list = NULL;
	char *res_str = NULL;

	slurmdb_init_res_rec(start_res, 0);

	for (i = 0; i < argc; i++) {
		int command_len = strlen(argv[i]);
		if (!xstrncasecmp(argv[i], "Where", MAX(command_len, 5))
		    || !xstrncasecmp(argv[i], "Set", MAX(command_len, 3)))
			i++;

		_set_res_rec(&i, argc, argv, name_list, cluster_list,
			     start_res);
	}

	if (exit_code) {
		FREE_NULL_LIST(name_list);
		FREE_NULL_LIST(cluster_list);
		slurmdb_destroy_res_rec(start_res);
		return SLURM_ERROR;
	} else if (!list_count(name_list)) {
		FREE_NULL_LIST(name_list);
		FREE_NULL_LIST(cluster_list);
		slurmdb_destroy_res_rec(start_res);
		exit_code = 1;
		fprintf(stderr, " Need name of resource to add.\n");
		return SLURM_SUCCESS;
	}

	if (!start_res->server) {
		/* assign some server name */
		start_res->server = xstrdup("slurmdb");
	}

	if (!g_res_list) {
		slurmdb_res_cond_t res_cond;
		slurmdb_init_res_cond(&res_cond, 0);
		/* 2 means return all resources even if they don't
		   have clusters attached to them.
		*/
		res_cond.with_clusters = 2;
		g_res_list = slurmdb_res_get(db_conn, &res_cond);
		if (!g_res_list) {
			exit_code=1;
			fprintf(stderr, " Problem getting system resources "
				"from database.  "
				"Contact your admin.\n");
			FREE_NULL_LIST(name_list);
			FREE_NULL_LIST(cluster_list);
			slurmdb_destroy_res_rec(start_res);
			return SLURM_ERROR;
		}
	}

	res_list = list_create(slurmdb_destroy_res_rec);

	itr = list_iterator_create(name_list);
	if (cluster_list)
		clus_itr = list_iterator_create(cluster_list);
	while ((name = list_next(itr))) {
		bool added = false;
		found_res = sacctmgr_find_res_from_list(
			g_res_list, NO_VAL, name, start_res->server);
		if (!found_res) {
			if (start_res->count == NO_VAL) {
				exit_code=1;
				fprintf(stderr,
					" Need to designate a resource "
					"count to initially add '%s'.\n", name);
				break;
			}
			res = xmalloc(sizeof(slurmdb_res_rec_t));
			slurmdb_init_res_rec(res, 0);
			res->name = xstrdup(name);
			res->description =
				xstrdup(start_res->description ?
					start_res->description : name);
			res->manager = xstrdup(start_res->manager);
			res->server = xstrdup(start_res->server);
			res->count = start_res->count;
			res->last_consumed = start_res->last_consumed;
			res->flags = start_res->flags;
			res->type = start_res->type;
			res->allocated = 0;

			xstrfmtcat(res_str, "  %s@%s\n",
				   res->name, res->server);
			list_append(res_list, res);
			added = true;
		}

		if (cluster_list && list_count(cluster_list)) {
			list_itr_t *found_itr = NULL;
			slurmdb_clus_res_rec_t *clus_res;
			char *cluster;

			if (found_res) {
				if (found_res->clus_res_list)
					found_itr = list_iterator_create(
						found_res->clus_res_list);
				res = xmalloc(sizeof(slurmdb_res_rec_t));
				slurmdb_init_res_rec(res, 0);
				res->count = found_res->count;
				res->last_consumed = found_res->last_consumed;
				res->id = found_res->id;
				xfree(res->name);
				res->name = xstrdup(found_res->name);
				res->type = found_res->type;
				xfree(res->server);
				res->server = xstrdup(found_res->server);
				res->flags = found_res->flags;
				res->allocated = found_res->allocated;
			}

			res->clus_res_list = list_create(
				slurmdb_destroy_clus_res_rec);

			while ((cluster = list_next(clus_itr))) {
				clus_res = NULL;
				if (found_itr) {
					while ((clus_res =
						list_next(found_itr))) {
						if (!xstrcmp(clus_res->cluster,
							     cluster))
							break;
					}
					list_iterator_reset(found_itr);
				}

				if (!clus_res) {
					if (!added) {
						xstrfmtcat(res_str,
							   "  %s@%s\n", name,
							   res->server);
						list_append(res_list, res);
						added = true;
					}
					clus_res = xmalloc(
						sizeof(slurmdb_clus_res_rec_t));
					list_append(res->clus_res_list,
						    clus_res);
					clus_res->cluster = xstrdup(cluster);
					clus_res->allowed =
						start_res->allocated;
					xstrfmtcat(res_str,
						   "   Cluster - %s\t%u\n",
						   cluster,
						   clus_res->allowed);
				}
			}

			if (!added)
				slurmdb_destroy_res_rec(res);

			if (found_itr)
				list_iterator_destroy(found_itr);

			list_iterator_reset(clus_itr);
		}
	}

	if (cluster_list)
		list_iterator_destroy(clus_itr);

	list_iterator_destroy(itr);

	FREE_NULL_LIST(name_list);
	FREE_NULL_LIST(cluster_list);

	if (exit_code) {
		rc = SLURM_ERROR;
		goto end_it;
	}

	if (!list_count(res_list)) {
		printf(" Nothing new added.\n");
		rc = SLURM_ERROR;
		goto end_it;
	}

	if (res_str) {
		char *tmp_str;
		switch (res->type) {
		case SLURMDB_RESOURCE_LICENSE:
			tmp_str = "License";
			break;
		default:
			tmp_str = "Unknown";
		}
		printf(" Adding Resource(s)\n%s", res_str);
		printf(" Settings\n");
		if (res->name)
			printf("  Name           = %s\n", res->name);
		if (res->server)
			printf("  Server         = %s\n", res->server);
		if (res->description)
			printf("  Description    = %s\n", res->description);
		if (res->manager)
			printf("  ServerType     = %s\n", res->manager);
		if (res->count != NO_VAL)
			printf("  Count          = %u\n", res->count);
		if (res->last_consumed != NO_VAL)
			printf("  LastConsumed   = %u\n", res->last_consumed);
		if (!(res->flags & SLURMDB_RES_FLAG_NOTSET)) {
			char *res_tmp_str = slurmdb_res_flags_str(res->flags);
			printf("  Flags          = %s\n", res_tmp_str);
			xfree(res_tmp_str);
		}
		printf("  Type           = %s\n", tmp_str);

		xfree(res_str);
	}

	if (list_count(res_list)) {
		notice_thread_init();
		rc = slurmdb_res_add(db_conn, res_list);
		notice_thread_fini();
	} else
		goto end_it;
	if (rc == SLURM_SUCCESS) {
		if (commit_check("Would you like to commit changes?")) {
			rc = slurmdb_connection_commit(db_conn, 1);
			if (rc != SLURM_SUCCESS)
				fprintf(stderr, " Error committing changes: %s\n",
					slurm_strerror(rc));
		} else {
			printf(" Changes Discarded\n");
			rc = slurmdb_connection_commit(db_conn, 0);
			if (rc != SLURM_SUCCESS)
				fprintf(stderr, " Error rolling back changes: %s\n",
					slurm_strerror(rc));
		}
	} else {
		exit_code = 1;
		fprintf(stderr, " Problem adding system resource: %s\n",
			slurm_strerror(rc));
		rc = SLURM_ERROR;
	}

end_it:
	FREE_NULL_LIST(res_list);
	slurmdb_destroy_res_rec(start_res);
	return rc;
}

extern int sacctmgr_list_res(int argc, char **argv)

{
	int rc = SLURM_SUCCESS;
	slurmdb_res_cond_t *res_cond = xmalloc(sizeof(slurmdb_res_cond_t));
 	int i=0;
	list_itr_t *itr = NULL;
	list_itr_t *itr2 = NULL;
	slurmdb_res_rec_t *res = NULL;
	slurmdb_clus_res_rec_t *clus_res = NULL;
	list_t *res_list = NULL;
	int field_count = 0;
	list_t *format_list = list_create(xfree_ptr);
	list_t *print_fields_list; /* types are of print_field_t */

	slurmdb_init_res_cond(res_cond, 0);

	for (i=0; i<argc; i++) {
		int command_len = strlen(argv[i]);
		if (!xstrncasecmp(argv[i], "Where", MAX(command_len, 5))
		    || !xstrncasecmp(argv[i], "Set", MAX(command_len, 3)))
			i++;
		_set_res_cond(&i, argc, argv, res_cond, format_list);
	}

	if (exit_code) {
		slurmdb_destroy_res_cond(res_cond);
		FREE_NULL_LIST(format_list);
		return SLURM_ERROR;
	} else if (!list_count(format_list)) {
		slurm_addto_char_list(
			format_list,
			"Name,Server,Type,Count,LastConsumed,Allocated,ServerType");
		if (res_cond->with_clusters)
			slurm_addto_char_list(
				format_list, "Cluster,Allowed");
		slurm_addto_char_list(format_list, "Flags");
	}

	print_fields_list = sacctmgr_process_format_list(format_list);
	FREE_NULL_LIST(format_list);

	if (exit_code) {
		rc = SLURM_ERROR;
		goto end_it;
	}
	res_list = slurmdb_res_get(db_conn, res_cond);

	if (!res_list) {
		exit_code=1;
		fprintf(stderr, " Problem with query.\n");
		rc = SLURM_ERROR;
		goto end_it;
	}
	itr = list_iterator_create(res_list);
	itr2 = list_iterator_create(print_fields_list);
	print_fields_header(print_fields_list);

	field_count = list_count(print_fields_list);
	while ((res = list_next(itr))) {
		if (res_cond->with_clusters && res->clus_res_list
		    && list_count(res->clus_res_list)) {
			list_itr_t *clus_itr = list_iterator_create(
				res->clus_res_list);
			while ((clus_res = list_next(clus_itr))) {
				_print_res_format(res, clus_res,
						  itr2, field_count);
			}
			list_iterator_destroy(clus_itr);
		} else
			_print_res_format(res, NULL, itr2, field_count);

	}
	list_iterator_destroy(itr2);
	list_iterator_destroy(itr);
	FREE_NULL_LIST(res_list);
end_it:
	FREE_NULL_LIST(print_fields_list);
	slurmdb_destroy_res_cond(res_cond);
	return rc;
}

extern int sacctmgr_modify_res(int argc, char **argv)

{
	int rc = SLURM_SUCCESS;
	slurmdb_res_cond_t *res_cond =
		xmalloc(sizeof(slurmdb_res_cond_t));
	slurmdb_res_rec_t *res =
		xmalloc(sizeof(slurmdb_res_rec_t));
	int i=0;
	int cond_set = 0, rec_set = 0, set = 0;
	list_t *ret_list = NULL;

	slurmdb_init_res_cond(res_cond, 0);
	slurmdb_init_res_rec(res, 0);

	for (i=0; i<argc; i++) {
		int command_len = strlen(argv[i]);
		if (!xstrncasecmp(argv[i], "Where", MAX(command_len, 5))) {
			i++;
			cond_set += _set_res_cond(&i, argc, argv,
						  res_cond, NULL);

		} else if (!xstrncasecmp(argv[i], "Set", MAX(command_len, 3))) {
			i++;
			rec_set += _set_res_rec(&i, argc, argv,
						NULL, NULL, res);
		} else {
			cond_set += _set_res_cond(&i, argc, argv,
						  res_cond, NULL);
		}
	}

	if (exit_code) {
		slurmdb_destroy_res_cond(res_cond);
		slurmdb_destroy_res_rec(res);
		return SLURM_ERROR;
	} else if (!rec_set) {
		exit_code=1;
		fprintf(stderr, " You didn't give me anything to set\n");
		slurmdb_destroy_res_cond(res_cond);
		slurmdb_destroy_res_rec(res);
		return SLURM_ERROR;
	} else if (!cond_set) {
		if (!commit_check("You didn't set any conditions with "
				  "'WHERE'.\n"
				  "Are you sure you want to continue?")) {
			printf("Aborted\n");
			slurmdb_destroy_res_cond(res_cond);
			slurmdb_destroy_res_rec(res);
			return SLURM_SUCCESS;
		}
	}

	if (res->count != NO_VAL && res_cond->cluster_list &&
			list_count(res_cond->cluster_list)) {
		fprintf(stderr, "Can't change \"count\" on a cluster-based "
			"resource. Remove cluster selection.\n");
		return SLURM_ERROR;
	} else if (res->last_consumed != NO_VAL && res_cond->cluster_list &&
		   list_count(res_cond->cluster_list)) {
		fprintf(stderr, "Can't change \"lastconsumed\" on a cluster-based resource. Remove cluster selection.\n");
		return SLURM_ERROR;
	} else if ((res->allocated != NO_VAL) && !res_cond->cluster_list) {
		fprintf(stderr, "Can't change \"allowed\" without "
			"specifying a cluster.\n");
		return SLURM_ERROR;
	}

	notice_thread_init();
	ret_list = slurmdb_res_modify(db_conn, res_cond, res);
	notice_thread_fini();
	if (ret_list && list_count(ret_list)) {
		char *object = NULL;
		list_itr_t *itr = list_iterator_create(ret_list);
		printf(" Modified server resource ...\n");
		while ((object = list_next(itr))) {
			printf("  %s\n", object);
		}
		list_iterator_destroy(itr);
		set = 1;
	} else if (ret_list) {
		printf("  Nothing modified\n");
		rc = SLURM_ERROR;
	} else if (errno == ESLURM_OVER_ALLOCATE) {
		exit_code=1;
		rc = SLURM_ERROR;
		fprintf(stderr,
			" If change was accepted it would look like this...\n");
		_print_overcommit(res, res_cond);

	} else {
		exit_code=1;
		fprintf(stderr, " Error with request: %s\n",
			slurm_strerror(errno));
		rc = SLURM_ERROR;
	}

	if (set) {
		if (commit_check("Would you like to commit changes?")) {
			rc = slurmdb_connection_commit(db_conn, 1);
			if (rc != SLURM_SUCCESS)
				fprintf(stderr, " Error committing changes: %s\n",
					slurm_strerror(rc));
		} else {
			printf(" Changes Discarded\n");
			rc = slurmdb_connection_commit(db_conn, 0);
			if (rc != SLURM_SUCCESS)
				fprintf(stderr, " Error rolling back changes: %s\n",
					slurm_strerror(rc));
		}
	}

	FREE_NULL_LIST(ret_list);

	slurmdb_destroy_res_cond(res_cond);
	slurmdb_destroy_res_rec(res);
	return rc;
}

extern int sacctmgr_delete_res(int argc, char **argv)

{
	int rc = SLURM_SUCCESS;
	slurmdb_res_cond_t *res_cond = xmalloc(sizeof(slurmdb_res_cond_t));
	int i=0;
	list_t *ret_list = NULL;
	list_itr_t *itr = NULL;
	int set = 0;
	char *name = NULL;

	slurmdb_init_res_cond(res_cond, 0);


	for (i=0; i<argc; i++) {
		int command_len = strlen(argv[i]);
		if (!xstrncasecmp(argv[i], "Where", MAX(command_len, 5))
		    || !xstrncasecmp(argv[i], "Set", MAX(command_len, 3)))
			i++;
		set += _set_res_cond(&i, argc, argv, res_cond, NULL);
	}

	if (!set) {
		exit_code=1;
		fprintf(stderr,
			" No conditions given to remove, not executing.\n");
		slurmdb_destroy_res_cond(res_cond);
		return SLURM_ERROR;
	} else if (set == -1) {
		slurmdb_destroy_res_cond(res_cond);
		return SLURM_ERROR;
	}

	notice_thread_init();
	ret_list = slurmdb_res_remove(db_conn, res_cond);
	notice_thread_fini();
	slurmdb_destroy_res_cond(res_cond);

	if (ret_list && list_count(ret_list)) {
		itr = list_iterator_create(ret_list);
		printf(" Deleting resource(s)...\n");

		while ((name = list_next(itr))) {
			printf("  %s\n", name);
		}
		list_iterator_destroy(itr);
		if (commit_check("Would you like to commit changes?")) {
			rc = slurmdb_connection_commit(db_conn, 1);
			if (rc != SLURM_SUCCESS)
				fprintf(stderr, " Error committing changes: %s\n",
					slurm_strerror(rc));
		} else {
			printf(" Changes Discarded\n");
			rc = slurmdb_connection_commit(db_conn, 0);
			if (rc != SLURM_SUCCESS)
				fprintf(stderr, " Error rolling back changes: %s\n",
					slurm_strerror(rc));
		}
	} else if (ret_list) {
		printf("  Nothing deleted\n");
		rc = SLURM_ERROR;
	} else {
		exit_code=1;
		fprintf(stderr, " Error with request: %s\n",
			slurm_strerror(errno));
		rc = SLURM_ERROR;
	}

	FREE_NULL_LIST(ret_list);

	xfree(name);
	return rc;
}
