/*****************************************************************************\
 *  federation_functions.c - functions dealing with Federations in the
 *                        accounting system.
 *****************************************************************************
 *  Copyright (C) SchedMD LLC.
 *
 *  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 int _set_cond(int *start, int argc, char **argv,
		     slurmdb_federation_cond_t *federation_cond,
		     list_t *format_list)
{
	int i;
	int set = 0;
	int end = 0;
	int command_len = 0;

	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], "where",
						 MAX(command_len, 5))) {
			continue;
		} else if (!end &&
			   !xstrncasecmp(argv[i], "WithDeleted",
					 MAX(command_len, 5))) {
			federation_cond->with_deleted = 1;
		} else if (!end && !xstrncasecmp(argv[i], "Tree",
						 MAX(command_len, 4))) {
			tree_display = 1;
		} else if (!end || !xstrncasecmp(argv[i], "Names",
						 MAX(command_len, 1))
			  || !xstrncasecmp(argv[i], "Federations",
					   MAX(command_len, 3))) {
			if (!federation_cond->federation_list)
				federation_cond->federation_list =
					list_create(xfree_ptr);
			if (slurm_addto_char_list(
					federation_cond->federation_list,
					argv[i]+end))
				set = 1;
		} else if (!end || !xstrncasecmp(argv[i], "Clusters",
						 MAX(command_len, 3))) {
			if (!federation_cond->cluster_list)
				federation_cond->cluster_list =
					list_create(xfree_ptr);
			if (slurm_addto_char_list(
						  federation_cond->cluster_list,
						  argv[i]+end))
				set = 1;
		} else if (!xstrncasecmp(argv[i], "Format",
					 MAX(command_len, 2))) {
			if (format_list)
				slurm_addto_char_list(format_list, argv[i]+end);
		} else {
			exit_code=1;
			fprintf(stderr, " Unknown condition: %s\n"
				" Use keyword 'set' to modify value\n",
				argv[i]);
			break;
		}
	}
	(*start) = i;

	return set;
}

static int _set_rec(int *start, int argc, char **argv,
		    list_t *name_list, slurmdb_federation_rec_t *fed)
{
	int i;
	int set = 0;
	int end = 0;
	int command_len = 0;
	int option = 0;
	bool allow_option = false;

	xassert(fed);

	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], "Name",
					   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, 2))) {
			allow_option = true;
			char *name = NULL;
			list_itr_t *itr;

			if (*(argv[i]+end) == '\0' &&
			    (option == '+' || option == '-')) {
				fprintf(stderr,
					" You didn't specify any clusters to %s\n",
					(option == '-') ? "remove" : "add");
				exit_code = 1;
				break;
			}

			list_t *cluster_names = list_create(xfree_ptr);
			if (slurm_addto_mode_char_list(cluster_names,
						       argv[i]+end, option) < 0)
			{
				FREE_NULL_LIST(cluster_names);
				exit_code = 1;
				break;
			}
			itr = list_iterator_create(cluster_names);
			fed->cluster_list =
				list_create(slurmdb_destroy_cluster_rec);
			while((name = list_next(itr))) {
				if (name[0] == '\0')
					continue;
				slurmdb_cluster_rec_t *cluster =
					xmalloc(sizeof(slurmdb_cluster_rec_t));
				slurmdb_init_cluster_rec(cluster, 0);
				cluster->name = xstrdup(name);
				list_append(fed->cluster_list, cluster);
			}
			list_iterator_destroy(itr);
			FREE_NULL_LIST(cluster_names);
			set = 1;
		} else if (!xstrncasecmp(argv[i], "Flags",
					 MAX(command_len, 2))) {
			allow_option = true;
			fed->flags = str_2_federation_flags(argv[i]+end,
								   option);
			if (fed->flags == FEDERATION_FLAG_NOTSET) {
				char *tmp_char = NULL;
				fed->flags = INFINITE;
				fed->flags &= (~FEDERATION_FLAG_NOTSET &
					       ~FEDERATION_FLAG_ADD &
					       ~FEDERATION_FLAG_REMOVE);
				tmp_char =
					slurmdb_federation_flags_str(
							fed->flags);
				fprintf(stderr,
					" Unknown federation flag used in:\n '%s'\n"
					" Valid federation flags are\n  '%s'\n",
					argv[i]+end, tmp_char);
				xfree(tmp_char);
				exit_code = 1;
			} else
				set = 1;
		} else {
			allow_option = true;
			exit_code = 1;
			fprintf(stderr,
				" 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 int _verify_federations(list_t *name_list, bool report_existing)
{
	int          rc        = SLURM_SUCCESS;
	char        *name      = NULL;
	list_t *temp_list = NULL;
	list_itr_t *itr = NULL;
	list_itr_t *itr_c = NULL;
	slurmdb_federation_cond_t fed_cond;

	if (!name_list || !list_count(name_list))
		return SLURM_SUCCESS;

	slurmdb_init_federation_cond(&fed_cond, 0);
	fed_cond.federation_list = name_list;

	temp_list = slurmdb_federations_get(db_conn, &fed_cond);
	if (!temp_list) {
		fprintf(stderr,
			" Problem getting federations from database.  "
			"Contact your admin.\n");
		return SLURM_ERROR;
	}

	itr_c = list_iterator_create(name_list);
	itr = list_iterator_create(temp_list);
	while((name = list_next(itr_c))) {
		slurmdb_federation_rec_t *fed_rec = NULL;

		list_iterator_reset(itr);
		while((fed_rec = list_next(itr))) {
			if (!strcasecmp(fed_rec->name, name))
				break;
		}
		if (fed_rec && report_existing) {
			printf(" This federation %s already exists.  "
			       "Not adding.\n", name);
			list_delete_item(itr_c);
		} else if (!fed_rec && !report_existing) {
			fprintf(stderr,
				" The federation %s doesn't exist.\n",
				name);
			rc = SLURM_ERROR;
		}
	}
	list_iterator_destroy(itr);
	list_iterator_destroy(itr_c);
	FREE_NULL_LIST(temp_list);
	if (!list_count(name_list) || rc != SLURM_SUCCESS) {
		return SLURM_ERROR;
	}

	return SLURM_SUCCESS;
}

static int _remove_existing_feds(list_t *name_list)
{
	return _verify_federations(name_list, 1);
}

extern int verify_federations_exist(list_t *name_list)
{
	return _verify_federations(name_list, 0);
}

/* Verify that clusters exist in the database.
 * Will remove clusters from list if they are already on the federation or if
 * a cluster is being removed and it doesn't exist on the federation.
 *
 * IN cluster_list: list of slurmdb_cluster_rec_t's with cluster names set.
 * IN fed_name: (optional) Name of federation that is being added/modified.
 * OUT existing_fed: Will be set to TRUE if a cluster in cluster_list is
 *                   assigned to a federation that is not fed_name. If fed_name
 *                   is set to NULL and a cluster is assigned to federation then
 *                   existing_fed will be set to TRUE.
 */
extern int verify_fed_clusters(list_t *cluster_list, const char *fed_name,
			       bool *existing_fed)
{
	char        *missing_str  = NULL;
	char        *existing_str = NULL;
	list_t *temp_list = NULL;
	list_itr_t *itr_db = NULL;
	list_itr_t *itr_c = NULL;
	slurmdb_cluster_rec_t *cluster_rec  = NULL;
	slurmdb_cluster_cond_t cluster_cond;

	/* Get existing clusters from database */
	slurmdb_init_cluster_cond(&cluster_cond, 0);
	cluster_cond.cluster_list = list_create(xfree_ptr);
	itr_c = list_iterator_create(cluster_list);
	while ((cluster_rec = list_next(itr_c))) {
		char *tmp_name = cluster_rec->name;
		if (!tmp_name)
			continue;

		if (tmp_name && (tmp_name[0] == '+' || tmp_name[0] == '-'))
			tmp_name++;
		list_append(cluster_cond.cluster_list, xstrdup(tmp_name));
	}
	temp_list = slurmdb_clusters_get(db_conn, &cluster_cond);
	FREE_NULL_LIST(cluster_cond.cluster_list);
	if (!temp_list) {
		fprintf(stderr,
			" Problem getting clusters from database.  "
			"Contact your admin.\n");
		list_iterator_destroy(itr_c);
		return SLURM_ERROR;
	}

	/* See if the clusters we are looking to add are in the cluster list
	 * from the db. */
	list_iterator_reset(itr_c);
	itr_db = list_iterator_create(temp_list);
	while((cluster_rec = list_next(itr_c))) {
		slurmdb_cluster_rec_t *db_rec = NULL;
		char *tmp_name = cluster_rec->name;
		if (!tmp_name)
			continue;

		if (tmp_name[0] == '+' || tmp_name[0] == '-')
			tmp_name++;

		list_iterator_reset(itr_db);
		while((db_rec = list_next(itr_db))) {
			if (!strcasecmp(db_rec->name, tmp_name))
				break;
		}
		if (!db_rec) {
			xstrfmtcat(missing_str, " The cluster %s doesn't exist."
				   " Please add first.\n", tmp_name);
		} else if (*cluster_rec->name != '-' &&
			   db_rec->fed.name && *db_rec->fed.name) {

			if (fed_name && !xstrcmp(fed_name, db_rec->fed.name)) {
				fprintf(stderr, " The cluster %s is already "
						"assigned to federation %s\n",
					db_rec->name, db_rec->fed.name);
				list_delete_item(itr_c);
			} else {
				xstrfmtcat(existing_str, " The cluster %s is "
					   "assigned to federation %s\n",
					   db_rec->name, db_rec->fed.name);
			}
		} else if (*cluster_rec->name == '-' &&
			   fed_name && xstrcmp(fed_name, db_rec->fed.name)) {
			fprintf(stderr, " The cluster %s isn't assigned to "
					"federation %s\n",
				db_rec->name, fed_name);
			list_delete_item(itr_c);
		} else if (db_rec->flags & CLUSTER_FLAG_EXT) {
			xstrfmtcat(missing_str, " The cluster %s is an external cluster and can't be added to a federation.\n",
				   db_rec->name);
		}
	}

	list_iterator_destroy(itr_db);
	list_iterator_destroy(itr_c);
	FREE_NULL_LIST(temp_list);
	if (missing_str) {
		fprintf(stderr, "%s", missing_str);
		xfree(missing_str);
		return SLURM_ERROR;
	} else if (existing_str) {
		*existing_fed = true;
		fprintf(stderr, "%s", existing_str);
	}
	xfree(existing_str);

	return SLURM_SUCCESS;
}

extern int sacctmgr_add_federation(int argc, char **argv)
{
	int rc = SLURM_SUCCESS;
	int i = 0, limit_set = 0;
	slurmdb_federation_rec_t *start_fed =
		xmalloc(sizeof(slurmdb_federation_rec_t));
	list_t *name_list = list_create(xfree_ptr);
	list_t *federation_list;
	list_itr_t *itr = NULL;
	char *name = NULL;

	slurmdb_init_federation_rec(start_fed, 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++;
		limit_set += _set_rec(&i, argc, argv, name_list, start_fed);
	}
	if (exit_code) {
		FREE_NULL_LIST(name_list);
		slurmdb_destroy_federation_rec(start_fed);
		return SLURM_ERROR;
	} else if (!list_count(name_list)) {
		slurmdb_destroy_federation_rec(start_fed);
		FREE_NULL_LIST(name_list);
		fprintf(stderr, " Need name of federation to add.\n");
		return SLURM_ERROR;
	} else if (_remove_existing_feds(name_list)) {
		FREE_NULL_LIST(name_list);
		slurmdb_destroy_federation_rec(start_fed);
		return SLURM_ERROR;
	}

	if ((list_count(name_list) > 1) &&
	    start_fed && start_fed->cluster_list &&
	    list_count(start_fed->cluster_list)) {
		slurmdb_destroy_federation_rec(start_fed);
		FREE_NULL_LIST(name_list);
		fprintf(stderr, " Can't assign clusters to multiple "
				"federations.\n");
		return SLURM_ERROR;
	}
	if (start_fed && start_fed->cluster_list &&
	    list_count(start_fed->cluster_list)) {
		bool existing_feds = false;

		if (list_count(name_list) > 1){
			slurmdb_destroy_federation_rec(start_fed);
			FREE_NULL_LIST(name_list);
			fprintf(stderr, " Can't assign clusters to "
				"multiple federations.\n");
			return SLURM_ERROR;
		}

		/* ensure that clusters exist in db */
		/* and if the clusters are already assigned to another fed. */
		if (verify_fed_clusters(start_fed->cluster_list, NULL,
					&existing_feds)) {
			FREE_NULL_LIST(name_list);
			slurmdb_destroy_federation_rec(start_fed);
			return SLURM_ERROR;
		} else if (existing_feds) {
			char *warning = "\nAre you sure you want to continue?";
			if (!commit_check(warning)) {
				FREE_NULL_LIST(name_list);
				slurmdb_destroy_federation_rec(start_fed);
				return SLURM_ERROR;
			}
		}
	}

	printf(" Adding Federation(s)\n");
	federation_list = list_create(slurmdb_destroy_federation_rec);
	itr = list_iterator_create(name_list);
	while((name = list_next(itr))) {
		slurmdb_federation_rec_t *fed = NULL;
		if (!name[0]) {
			fprintf(stderr, " Skipping blank fed name.\n");
			continue;
		}
		fed = xmalloc(sizeof(slurmdb_federation_rec_t));
		slurmdb_init_federation_rec(fed, 0);
		list_append(federation_list, fed);
		slurmdb_copy_federation_rec(fed, start_fed);
		fed->name = xstrdup(name);
		printf("  %s\n", fed->name);
	}
	list_iterator_destroy(itr);
	FREE_NULL_LIST(name_list);

	if (limit_set) {
		printf(" Settings\n");
		sacctmgr_print_federation(start_fed);
	}
	slurmdb_destroy_federation_rec(start_fed);

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

	notice_thread_init();
	rc = slurmdb_federations_add(db_conn, federation_list);
	notice_thread_fini();

	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 federation(s): %s\n",
			slurm_strerror(rc));
		rc = SLURM_ERROR;
	}

end_it:
	FREE_NULL_LIST(federation_list);

	return rc;
}

extern int sacctmgr_list_federation(int argc, char **argv)
{
	int rc = SLURM_SUCCESS;
	slurmdb_federation_cond_t *federation_cond =
		xmalloc(sizeof(slurmdb_federation_cond_t));
	list_t *federation_list;
	int i=0;
	list_itr_t *itr = NULL;
	list_itr_t *itr2 = NULL;
	slurmdb_federation_rec_t *fed = NULL;
	bool print_clusters = false;

	int field_count = 0;

	print_field_t *field = NULL;

	list_t *format_list = list_create(xfree_ptr);
	list_t *print_fields_list; /* types are of print_field_t */

	slurmdb_init_federation_cond(federation_cond, 0);
	federation_cond->federation_list = list_create(xfree_ptr);
	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_cond(&i, argc, argv, federation_cond, format_list);
	}

	if (exit_code) {
		slurmdb_destroy_federation_cond(federation_cond);
		FREE_NULL_LIST(format_list);
		return SLURM_ERROR;
	}

	if (!list_count(format_list)) {
		slurm_addto_char_list(format_list,
				      "Federation,Cluster,ID%2,"
				      "Features,FedState");
	}

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

	if (exit_code) {
		slurmdb_destroy_federation_cond(federation_cond);
		FREE_NULL_LIST(print_fields_list);
		return SLURM_ERROR;
	}

	federation_list = slurmdb_federations_get(db_conn, federation_cond);
	slurmdb_destroy_federation_cond(federation_cond);

	if (!federation_list) {
		exit_code=1;
		fprintf(stderr, " Problem with query.\n");
		FREE_NULL_LIST(print_fields_list);
		return SLURM_ERROR;
	}

	itr = list_iterator_create(federation_list);
	itr2 = list_iterator_create(print_fields_list);
	print_fields_header(print_fields_list);

	field_count = list_count(print_fields_list);

	/* only print clusters if a cluster field is requested */
	while((field = list_next(itr2))) {
		switch (field->type) {
		case PRINT_CLUSTER:
		case PRINT_FEDSTATE:
		case PRINT_FEDSTATERAW:
		case PRINT_ID:
			print_clusters = true;
			break;
		}
	}
	list_iterator_reset(itr2);

	while ((fed = list_next(itr))) {
		int      curr_inx   = 1;
		char    *tmp_str    = NULL;
		uint32_t tmp_uint32 = 0;
		slurmdb_cluster_rec_t *tmp_cluster = NULL;
		list_itr_t *itr3 =
			list_iterator_create(fed->cluster_list);

		if (!tree_display && print_clusters)
			tmp_cluster = list_next(itr3);

		do {
			while((field = list_next(itr2))) {
				switch(field->type) {
				/* Federation Specific Fields */
				case PRINT_FEDERATION:
					if (tree_display && tmp_cluster)
						tmp_str = NULL;
					else
						tmp_str = fed->name;
					field->print_routine(
						field, tmp_str,
						(curr_inx == field_count));
					break;
				case PRINT_FLAGS:
					if (tree_display && tmp_cluster)
						tmp_str = NULL;
					else {
						tmp_str =
						slurmdb_federation_flags_str(
								fed->flags);
					}
					field->print_routine(
						field, tmp_str,
						(curr_inx == field_count));

					if (tmp_str)
						xfree(tmp_str);
					break;

				/* Cluster Specific Fields */
				case PRINT_CLUSTER:
					if (!tmp_cluster)
						tmp_str = NULL;
					else
						tmp_str = tmp_cluster->name;
					field->print_routine(
						field, tmp_str,
						(curr_inx == field_count));
					break;
				case PRINT_FEATURES:
				{
					list_t *tmp_list = NULL;
					if (tmp_cluster)
						tmp_list = tmp_cluster->
							fed.feature_list;
					field->print_routine(
						field, &tmp_list,
						(curr_inx == field_count));
					break;
				}
				case PRINT_FEDSTATE:
					if (!tmp_cluster)
						tmp_str = NULL;
					else {
						tmp_str =
						slurmdb_cluster_fed_states_str(
							tmp_cluster->fed.state);
					}
					field->print_routine(
						field, tmp_str,
						(curr_inx == field_count));
					break;
				case PRINT_FEDSTATERAW:
					if (!tmp_cluster)
						tmp_uint32 = NO_VAL;
					else
						tmp_uint32 =
							tmp_cluster->fed.state;
					field->print_routine(
						field, &tmp_uint32,
						(curr_inx == field_count));
					break;
				case PRINT_ID:
					if (!tmp_cluster)
						tmp_uint32 = NO_VAL;
					else
						tmp_uint32 =
							tmp_cluster->fed.id;
					field->print_routine(
						field, &tmp_uint32,
						(curr_inx == field_count));
					break;
				default:
					field->print_routine(
						field, NULL,
						(curr_inx == field_count));
					break;
				}
				curr_inx++;
			}
			list_iterator_reset(itr2);
			printf("\n");
		} while(print_clusters && (tmp_cluster = list_next(itr3)));
		list_iterator_destroy(itr3);
	}

	list_iterator_destroy(itr2);
	list_iterator_destroy(itr);
	FREE_NULL_LIST(federation_list);
	FREE_NULL_LIST(print_fields_list);

	return rc;
}

/* Add clusters to be removed if "setting" a federation to a specific set of
 * clusters or clearing all clusters.
 *
 * IN cluster_list: list of slurmdb_cluster_rec_t's with cluster names set that
 *                  are to be "set" on the federation the federation.
 * IN federation: name of the federation that is being added/modified.
 */
static int _add_clusters_to_remove(list_t *cluster_list, const char *federation)
{
	list_t *db_list = NULL;
	list_itr_t *db_itr = NULL;
	slurmdb_federation_cond_t db_cond;
	slurmdb_federation_rec_t *db_rec = NULL;
	slurmdb_cluster_rec_t    *db_cluster = NULL;

	slurmdb_init_federation_cond(&db_cond, 0);
	db_cond.federation_list = list_create(xfree_ptr);
	list_append(db_cond.federation_list, xstrdup(federation));

	db_list = slurmdb_federations_get(db_conn, &db_cond);
	if (!db_list || !list_count(db_list)) {
		fprintf(stderr, " Problem getting federations "
			"from database. Contact your admin.\n");
		return SLURM_ERROR;
	}
	FREE_NULL_LIST(db_cond.federation_list);
	db_rec = list_peek(db_list);
	db_itr = list_iterator_create(db_rec->cluster_list);
	while ((db_cluster = list_next(db_itr))) {
		bool found_cluster = false;
		slurmdb_cluster_rec_t *orig_cluster = NULL;
		list_itr_t *orig_itr = list_iterator_create(cluster_list);

		/* Figure out if cluster in cluster_list is already on the
		 * federation. If it is, don't add to list to remove */
		while ((orig_cluster = list_next(orig_itr))) {
			char *db_name = db_cluster->name;
			if (*db_name == '+' || *db_name == '-')
				++db_name;
			if (!xstrcmp(orig_cluster->name, db_name)) {
				found_cluster = true;
				break;
			}
		}
		list_iterator_destroy(orig_itr);
		if (found_cluster)
			continue;

		slurmdb_cluster_rec_t *cluster =
			xmalloc(sizeof(slurmdb_cluster_rec_t));
		slurmdb_init_cluster_rec(cluster, 0);
		cluster->name = xstrdup_printf("-%s", db_cluster->name);
		list_append(cluster_list, cluster);
	}
	list_iterator_destroy(db_itr);
	FREE_NULL_LIST(db_list);

	return SLURM_SUCCESS;
}

/* Change add mode of clusters to be added to federation to += mode.
 * A cluster that is already part of a federation will be removed from the list
 * to set the federation clusters to, so all assigns need to be changed to '+'
 * plus modes. Clusters that are to be removed from the federation clustesr will
 * have already been added to the list in '-' mode.
 */
static int _change_assigns_to_adds(list_t *cluster_list)
{
	int rc = SLURM_SUCCESS;
	list_itr_t *itr = list_iterator_create(cluster_list);
	slurmdb_cluster_rec_t *cluster = NULL;

	while ((cluster = list_next(itr))) {
		if (cluster->name && *cluster->name &&
		    (*cluster->name != '-' && *cluster->name != '+')) {
			char *tmp_name = xstrdup_printf("+%s", cluster->name);
			xfree(cluster->name);
			cluster->name = tmp_name;
		}
	}

	return rc;
}

extern int sacctmgr_modify_federation(int argc, char **argv)
{
	int rc = SLURM_SUCCESS;
	int i=0;
	int cond_set = 0, prev_set = 0, rec_set = 0, set = 0;
	list_t *ret_list = NULL;
	slurmdb_federation_cond_t *federation_cond =
		xmalloc(sizeof(slurmdb_federation_cond_t));
	slurmdb_federation_rec_t *federation =
		xmalloc(sizeof(slurmdb_federation_rec_t));

	slurmdb_init_federation_cond(federation_cond, 0);
	slurmdb_init_federation_rec(federation, 0);

	for (i=0; i<argc; i++) {
		int command_len = strlen(argv[i]);
		if (!xstrncasecmp(argv[i], "Where", MAX(command_len, 5))) {
			i++;
			prev_set = _set_cond(&i, argc, argv,
					     federation_cond, NULL);
			cond_set |= prev_set;
		} else if (!xstrncasecmp(argv[i], "Set", MAX(command_len, 3))) {
			i++;
			prev_set = _set_rec(&i, argc, argv, NULL, federation);
			rec_set |= prev_set;
		} else {
			prev_set = _set_cond(&i, argc, argv,
					     federation_cond, NULL);
			cond_set |= prev_set;
		}
	}

	if (exit_code) {
		rc = SLURM_ERROR;
		goto end_it;
	} else if (!rec_set) {
		exit_code=1;
		fprintf(stderr, " You didn't give me anything to set\n");
		rc = SLURM_ERROR;
		goto end_it;
	} 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");
			rc = SLURM_SUCCESS;
			goto end_it;
		}
	} else if (verify_federations_exist(
					federation_cond->federation_list)) {
		rc = SLURM_ERROR;
		goto end_it;
	}

	if (federation->cluster_list) {
		bool existing_feds = false;
		char *mod_fed = NULL;
		slurmdb_cluster_rec_t *tmp_c = NULL;
		list_t *cluster_list = federation->cluster_list;

		if (!federation_cond->federation_list ||
		    (list_count(federation_cond->federation_list) != 1)) {
			fprintf(stderr, " Can't assign clusters to multiple federations.\n");
			rc = SLURM_ERROR;
			goto end_it;
		}

		/* Add all clusters that need to be removed if clearing all
		 * clusters or add clusters that will be removed if setting
		 * clusters to specific set. */
		mod_fed = list_peek(federation_cond->federation_list);
		if ((!list_count(cluster_list) ||
		     ((tmp_c = list_peek(cluster_list)) &&
		      *tmp_c->name != '-' && *tmp_c->name != '+')) &&
		    ((rc = _add_clusters_to_remove(cluster_list, mod_fed)) ||
		     (rc = _change_assigns_to_adds(cluster_list)))) {
			goto end_it;
		} else if ((rc = verify_fed_clusters(cluster_list, mod_fed,
						     &existing_feds))) {
			goto end_it;
		} else if (!list_count(cluster_list)) {
			printf("Nothing to change\n");
			rc = SLURM_ERROR;
			goto end_it;
		} else if (existing_feds) {
			char *warning = "\nAre you sure you want to continue?";
			if (!commit_check(warning)) {
				rc = SLURM_ERROR;
				goto end_it;
			}
		}
	}

	printf(" Setting\n");
	sacctmgr_print_federation(federation);

	notice_thread_init();
	ret_list = slurmdb_federations_modify(db_conn,
					      federation_cond,
					      federation);

	printf(" Modified federation...\n");
	if (ret_list && list_count(ret_list)) {
		char *object = NULL;
		list_itr_t *itr = list_iterator_create(ret_list);
		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 {
		exit_code=1;
		fprintf(stderr, " Error with request: %s\n",
			slurm_strerror(errno));
		rc = SLURM_ERROR;
	}

	FREE_NULL_LIST(ret_list);

	notice_thread_fini();

	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));
		}
	}
end_it:
	slurmdb_destroy_federation_cond(federation_cond);
	slurmdb_destroy_federation_rec(federation);

	return rc;
}

extern int sacctmgr_delete_federation(int argc, char **argv)
{
	int rc = SLURM_SUCCESS;
	slurmdb_federation_cond_t *fed_cond =
		xmalloc(sizeof(slurmdb_federation_cond_t));
	int i=0;
	list_t *ret_list = NULL;
	int cond_set = 0, prev_set;

	slurmdb_init_federation_cond(fed_cond, 0);
	fed_cond->federation_list = list_create(xfree_ptr);

	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++;
		prev_set = _set_cond(&i, argc, argv, fed_cond, NULL);
		cond_set |= prev_set;
	}

	if (exit_code) {
		slurmdb_destroy_federation_cond(fed_cond);
		return SLURM_ERROR;
	} else if (!cond_set) {
		exit_code=1;
		fprintf(stderr,
			" No conditions given to remove, not executing.\n");
		slurmdb_destroy_federation_cond(fed_cond);
		return SLURM_ERROR;
	}

	if (!list_count(fed_cond->federation_list)) {
		exit_code=1;
		fprintf(stderr,
			"problem with delete request.  "
			"Nothing given to delete.\n");
		slurmdb_destroy_federation_cond(fed_cond);
		return SLURM_SUCCESS;
	}
	notice_thread_init();
	ret_list = slurmdb_federations_remove(db_conn, fed_cond);
	rc = errno;
	notice_thread_fini();

	slurmdb_destroy_federation_cond(fed_cond);

	if (ret_list && list_count(ret_list)) {
		char *object = NULL;
		list_itr_t *itr = list_iterator_create(ret_list);

		printf(" Deleting federations...\n");
		while((object = list_next(itr))) {
			printf("  %s\n", object);
		}
		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);

	return rc;
}
