/*****************************************************************************\
 *  common.c - common functions for generating reports
 *             from accounting infrastructure.
 *****************************************************************************
 *  Copyright (C) SchedMD LLC.
 *  Copyright (C) 2008 Lawrence Livermore National Security.
 *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
 *  Written by Danny Auble <da@llnl.gov>
 *  CODE-OCEC-09-009. All rights reserved.
 *
 *  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 "sreport.h"
#include "src/common/proc_args.h"

int sort_user_tres_id = TRES_CPU; /* controls sorting users (sort_user_dec) */

extern char *sreport_get_time_str(uint64_t value, uint64_t total_time)
{
	char *output = NULL;

	if (!total_time)
		total_time = 1;

	if (!(value == NO_VAL) || (value == INFINITE)) {
		double percent = (double)value;
		double temp_d = (double)value;

		switch (time_format) {
		case SLURMDB_REPORT_TIME_SECS:
			output = xstrdup_printf("%"PRIu64"", value);
			break;
		case SLURMDB_REPORT_TIME_MINS:
			temp_d /= 60;
			output = xstrdup_printf("%.0lf", temp_d);
			break;
		case SLURMDB_REPORT_TIME_HOURS:
			temp_d /= 3600;
			output = xstrdup_printf("%.0lf", temp_d);
			break;
		case SLURMDB_REPORT_TIME_PERCENT:
			percent /= total_time;
			percent *= 100;
			output = xstrdup_printf("%.2lf%%", percent);
			break;
		case SLURMDB_REPORT_TIME_SECS_PER:
			percent /= total_time;
			percent *= 100;
			output = xstrdup_printf("%"PRIu64"(%.2lf%%)",
						value, percent);
			break;
		case SLURMDB_REPORT_TIME_MINS_PER:
			percent /= total_time;
			percent *= 100;
			temp_d /= 60;
			output = xstrdup_printf("%.0lf(%.2lf%%)",
						temp_d, percent);
			break;
		case SLURMDB_REPORT_TIME_HOURS_PER:
			percent /= total_time;
			percent *= 100;
			temp_d /= 3600;
			output = xstrdup_printf("%.0lf(%.2lf%%)",
						temp_d, percent);
			break;
		default:
			temp_d /= 60;
			output = xstrdup_printf("%.0lf", temp_d);
			break;
		}
	}
	return output;
}

extern int parse_option_end(char *option)
{
	int end = 0;

	if (!option)
		return 0;

	while(option[end] && option[end] != '=')
		end++;
	if (!option[end])
		return 0;
	end++;
	return end;
}


/* Do not allow the endtime request for sreport to exceed 'now'. */
extern time_t sanity_check_endtime(time_t endtime)
{
	time_t now = time(NULL);

	if (endtime > now)
		endtime = now;

	return endtime;
}

/* you need to xfree whatever is sent from here */
extern char *strip_quotes(char *option, int *increased)
{
	int end = 0;
	int i=0, start=0;
	char *meat = NULL;

	if (!option)
		return NULL;

	/* first strip off the ("|')'s */
	if (option[i] == '\"' || option[i] == '\'')
		i++;
	start = i;

	while (option[i]) {
		if (option[i] == '\"' || option[i] == '\'') {
			end++;
			break;
		}
		i++;
	}
	end += i;

	meat = xmalloc((i-start)+1);
	memcpy(meat, option+start, (i-start));

	if (increased)
		(*increased) += end;

	return meat;
}

extern void addto_char_list(list_t *char_list, char *names)
{
	int i = 0, start = 0;
	char *name = NULL, *tmp_char = NULL;
	list_itr_t *itr = NULL;

	if (!char_list) {
		error("No list was given to fill in");
		return;
	}

	itr = list_iterator_create(char_list);
	if (names) {
		if (names[i] == '\"' || names[i] == '\'')
			i++;
		start = i;
		while(names[i]) {
			if (names[i] == '\"' || names[i] == '\'')
				break;
			else if (names[i] == ',') {
				if ((i-start) > 0) {
					name = xmalloc((i-start+1));
					memcpy(name, names+start, (i-start));

					while((tmp_char = list_next(itr))) {
						if (!xstrcasecmp(tmp_char,
								 name))
							break;
					}

					if (!tmp_char)
						list_append(char_list, name);
					else
						xfree(name);
					list_iterator_reset(itr);
				}
				i++;
				start = i;
			}
			i++;
		}
		if ((i-start) > 0) {
			name = xmalloc((i-start)+1);
			memcpy(name, names+start, (i-start));
			while((tmp_char = list_next(itr))) {
				if (!xstrcasecmp(tmp_char, name))
					break;
			}

			if (!tmp_char)
				list_append(char_list, name);
			else
				xfree(name);
		}
	}
	list_iterator_destroy(itr);
}

/*
 * Comparator to sort users from higher usage of sort_user_tres_id to smallest
 *
 * returns: 1: user_a > user_b   0: user_a == user_b   -1: user_a < user_b
 *
 */
extern int sort_user_dec(void *v1, void *v2)
{
	slurmdb_report_user_rec_t *user_a;
	slurmdb_report_user_rec_t *user_b;
	int diff;

	user_a = *(slurmdb_report_user_rec_t **)v1;
	user_b = *(slurmdb_report_user_rec_t **)v2;

	if (sort_flag == SLURMDB_REPORT_SORT_TIME) {
		slurmdb_tres_rec_t *tres_a, *tres_b;

		if (!user_a->tres_list || !user_b->tres_list)
			return 0;

		if (!(tres_a = list_find_first(user_a->tres_list,
					       slurmdb_find_tres_in_list,
					       &sort_user_tres_id)))
			return 1;

		if (!(tres_b = list_find_first(user_b->tres_list,
					       slurmdb_find_tres_in_list,
					       &sort_user_tres_id)))
			return -1;


		if (tres_a->alloc_secs > tres_b->alloc_secs)
			return -1;
		else if (tres_a->alloc_secs < tres_b->alloc_secs)
			return 1;
	}

	if (!user_a->name || !user_b->name)
		return 0;

	diff = xstrcmp(user_a->name, user_b->name);

	if (diff > 0)
		return 1;
	else if (diff < 0)
		return -1;

	return 0;

}

/*
 * Comparator used for sorting clusters alphabetically
 *
 * returns: 1: cluster_a > cluster_b
 *           0: cluster_a == cluster_b
 *           -1: cluster_a < cluster_b
 *
 */
extern int sort_cluster_dec(void *v1, void *v2)
{
	int diff;
	slurmdb_report_cluster_rec_t *cluster_a;
	slurmdb_report_cluster_rec_t *cluster_b;

	cluster_a = *(slurmdb_report_cluster_rec_t **)v1;
	cluster_b = *(slurmdb_report_cluster_rec_t **)v2;

	if (!cluster_a->name || !cluster_b->name)
		return 0;

	diff = xstrcmp(cluster_a->name, cluster_b->name);

	if (diff > 0)
		return 1;
	else if (diff < 0)
		return -1;

	return 0;
}

/*
 * Comparator used for sorting assocs alphabetically by acct and then
 * by user.  The association with a total count of time is at the top
 * of the accts.
 *
 * returns: -1: assoc_a > assoc_b
 *           0: assoc_a == assoc_b
 *           1: assoc_a < assoc_b
 *
 */
extern int sort_assoc_dec(void *v1, void *v2)
{
	int diff;
	slurmdb_report_assoc_rec_t *assoc_a;
	slurmdb_report_assoc_rec_t *assoc_b;

	assoc_a = *(slurmdb_report_assoc_rec_t **)v1;
	assoc_b = *(slurmdb_report_assoc_rec_t **)v2;

	if (!assoc_a->acct || !assoc_b->acct)
		return 0;

	diff = xstrcmp(assoc_a->acct, assoc_b->acct);

	if (diff > 0)
		return 1;
	else if (diff < 0)
		return -1;

	if (!assoc_a->user && assoc_b->user)
		return 1;
	else if (!assoc_b->user)
		return -1;

	diff = xstrcmp(assoc_a->user, assoc_b->user);

	if (diff > 0)
		return 1;
	else if (diff < 0)
		return -1;


	return 0;
}

extern int get_uint(char *in_value, uint32_t *out_value, char *type)
{
	char *ptr = NULL, *meat = NULL;
	long num;

	if (!(meat = strip_quotes(in_value, NULL))) {
		error("Problem with strip_quotes");
		return SLURM_ERROR;
	}
	num = strtol(meat, &ptr, 10);
	if ((num == 0) && ptr && ptr[0]) {
		error("Invalid value for %s (%s)", type, meat);
		xfree(meat);
		return SLURM_ERROR;
	}
	xfree(meat);

	if (num < 0)
		*out_value = INFINITE;		/* flag to clear */
	else
		*out_value = (uint32_t) num;
	return SLURM_SUCCESS;
}

extern void sreport_set_tres_recs(slurmdb_tres_rec_t **cluster_tres_rec,
				  slurmdb_tres_rec_t **tres_rec,
				  list_t *cluster_tres_list, list_t *tres_list,
				  slurmdb_tres_rec_t *tres_rec_in)
{
	if (!(*cluster_tres_rec = list_find_first(cluster_tres_list,
						  slurmdb_find_tres_in_list,
						  &tres_rec_in->id))) {
		debug2("No cluster TRES %s%s%s(%d)",
		       tres_rec_in->type,
		       tres_rec_in->name ? "/" : "",
		       tres_rec_in->name ? tres_rec_in->name : "",
		       tres_rec_in->id);
	}

	if (!(*tres_rec = list_find_first(tres_list,
					  slurmdb_find_tres_in_list,
					  &tres_rec_in->id))) {
		debug2("No TRES %s%s%s(%d)",
		       tres_rec_in->type,
		       tres_rec_in->name ? "/" : "",
		       tres_rec_in->name ? tres_rec_in->name : "",
		       tres_rec_in->id);
	} else if (!(*tres_rec)->alloc_secs) {
		debug2("No TRES %s%s%s(%d) usage",
		       tres_rec_in->type,
		       tres_rec_in->name ? "/" : "",
		       tres_rec_in->name ? tres_rec_in->name : "",
		       tres_rec_in->id);
	}
}

extern void sreport_set_usage_col_width(print_field_t *field, uint64_t number)
{
	uint64_t order, max_order;

	//info("got %p %"PRIu64, field, number);
	if (!field)
		return;

	order = 100000000;
	max_order = order * 100000000000000000;

	/* smallest usage we want if this changes change order and
	 * max_order appropriately */
	field->len = 8;

	while (order < max_order) {
		if (number < order)
			break;

		field->len++;
		order *= 10;
	}

	if (time_format == SLURMDB_REPORT_TIME_SECS_PER
	    || time_format == SLURMDB_REPORT_TIME_MINS_PER
	    || time_format == SLURMDB_REPORT_TIME_HOURS_PER)
		field->len += 9;
}

extern void sreport_set_usage_column_width(print_field_t *usage_field,
					   print_field_t *energy_field,
					   list_t *slurmdb_report_cluster_list)
{
	uint64_t max_usage = 0, max_energy = 0;
	list_itr_t *tres_itr, *cluster_itr;
	slurmdb_report_cluster_rec_t *slurmdb_report_cluster = NULL;

	xassert(slurmdb_report_cluster_list);

	tres_itr = list_iterator_create(tres_list);
	cluster_itr = list_iterator_create(slurmdb_report_cluster_list);
	while ((slurmdb_report_cluster = list_next(cluster_itr))) {
		slurmdb_tres_rec_t *tres, *tres_rec;
		list_t *use_list = slurmdb_report_cluster->tres_list;

		/* The first association will always be the largest
		 * count of any TRES, so just peek at it.  If the
		 * cluster doesn't have associations for some reason
		 * use the cluster main one which has the total time.
		 */

		if (slurmdb_report_cluster->assoc_list) {
			slurmdb_report_assoc_rec_t *slurmdb_report =
				list_peek(slurmdb_report_cluster->assoc_list);
			if (slurmdb_report)
				use_list = slurmdb_report->tres_list;
		} else if (slurmdb_report_cluster->user_list) {
			slurmdb_report_user_rec_t *slurmdb_report;
			list_sort(slurmdb_report_cluster->user_list,
				  (ListCmpF)sort_user_dec);
			slurmdb_report =
				list_peek(slurmdb_report_cluster->user_list);
			if (slurmdb_report)
				use_list = slurmdb_report->tres_list;
		} else {
			error("%s: unknown type of slurmdb_report_cluster "
			      "given for cluster %s",
			      __func__, slurmdb_report_cluster->name);
			continue;
		}

		if (energy_field) {
			uint32_t tres_id = TRES_CPU;
			if ((tres_rec = list_find_first(
				     use_list,
				     slurmdb_find_tres_in_list,
				     &tres_id))) {
				max_usage = MAX(max_usage,
						tres_rec->alloc_secs);
			}
			tres_id = TRES_ENERGY;
			if ((tres_rec = list_find_first(
				     use_list,
				     slurmdb_find_tres_in_list,
				     &tres_id))) {
				max_energy = MAX(max_energy,
						 tres_rec->alloc_secs);
			}
		} else {
			list_iterator_reset(tres_itr);
			while ((tres = list_next(tres_itr))) {
				if (tres->id == NO_VAL)
					continue;
				if (!(tres_rec = list_find_first(
					      use_list,
					      slurmdb_find_tres_in_list,
					      &tres->id)))
					continue;
				max_usage = MAX(max_usage,
						tres_rec->alloc_secs);
			}
		}
	}
	list_iterator_destroy(tres_itr);
	list_iterator_destroy(cluster_itr);

	sreport_set_usage_col_width(usage_field, max_usage);
	sreport_set_usage_col_width(energy_field, max_energy);
}

/* Return 1 if UID for two association records match */
static int _match_assoc(void *x, void *key)
{
	slurmdb_report_assoc_rec_t *orig_report_assoc;
	slurmdb_report_assoc_rec_t *dup_report_assoc;

	orig_report_assoc = (slurmdb_report_assoc_rec_t *) key;
	dup_report_assoc  = (slurmdb_report_assoc_rec_t *) x;
	if (!xstrcmp(orig_report_assoc->acct, dup_report_assoc->acct) &&
	    !xstrcmp(orig_report_assoc->user, dup_report_assoc->user))
		return 1;
	return 0;
}

/* Return 1 if a slurmdb association record has NULL tres_list */
static int _find_empty_assoc_tres(void *x, void *key)
{
	slurmdb_report_assoc_rec_t *dup_report_assoc;

	dup_report_assoc = (slurmdb_report_assoc_rec_t *) x;
	if (dup_report_assoc->tres_list == NULL)
		return 1;
	return 0;
}

/* For duplicate user/account records, combine TRES records into the original
 * list and purge the duplicate records */
extern void combine_assoc_tres(list_t *first_assoc_list, list_t *new_assoc_list)
{
	slurmdb_report_assoc_rec_t *orig_report_assoc = NULL;
	slurmdb_report_assoc_rec_t *dup_report_assoc = NULL;
	list_itr_t *iter = NULL;

	if (!first_assoc_list || !new_assoc_list)
		return;

	iter = list_iterator_create(first_assoc_list);
	while ((orig_report_assoc = list_next(iter))) {
		dup_report_assoc = list_find_first(new_assoc_list,
						   _match_assoc,
						   orig_report_assoc);
		if (!dup_report_assoc)
			continue;
		combine_tres_list(orig_report_assoc->tres_list,
				  dup_report_assoc->tres_list);
		FREE_NULL_LIST(dup_report_assoc->tres_list);
	}
	list_iterator_destroy(iter);

	(void) list_delete_all(new_assoc_list, _find_empty_assoc_tres, NULL);
	list_transfer(first_assoc_list, new_assoc_list);
}

/* Return 1 if two TRES records have the same TRES ID */
static int _match_tres_id(void *x, void *key)
{
	slurmdb_tres_rec_t *orig_tres = (slurmdb_tres_rec_t *) key;
	slurmdb_tres_rec_t *dup_tres = (slurmdb_tres_rec_t *) x;

	if (orig_tres->id == dup_tres->id)
		return 1;
	return 0;
}

/* Return 1 if a TRES alloc_secs is zero, the entry has already been merged */
static int _zero_alloc_secs(void *x, void *key)
{
	slurmdb_tres_rec_t *dup_tres;

	dup_tres = (slurmdb_tres_rec_t *) x;
	if (dup_tres->alloc_secs == 0)
		return 1;
	return 0;
}

/* Given two TRES lists, combine the content of the second with the first,
 * adding the counts for duplicate TRES IDs */
extern void combine_tres_list(list_t *orig_tres_list, list_t *dup_tres_list)
{
	slurmdb_tres_rec_t *orig_tres, *dup_tres;
	list_itr_t *iter = NULL;

	if (!orig_tres_list || !dup_tres_list)
		return;

	/* Merge counts for common TRES */
	iter = list_iterator_create(orig_tres_list);
	while ((orig_tres = list_next(iter))) {
		dup_tres = list_find_first(dup_tres_list, _match_tres_id,
					   orig_tres);
		if (!dup_tres)
			continue;

		orig_tres->alloc_secs += dup_tres->alloc_secs;
		orig_tres->rec_count  += dup_tres->rec_count;
		orig_tres->count      += dup_tres->count;
		dup_tres->alloc_secs  = 0;
	}
	list_iterator_destroy(iter);

	/* Now transfer TRES records that exists only in the duplicate */
	list_delete_all(dup_tres_list, _zero_alloc_secs, NULL);
	list_transfer(orig_tres_list, dup_tres_list);
}


/* Return 1 if a slurmdb user record has NULL tres_list */
static int _find_empty_user_tres(void *x, void *key)
{
	slurmdb_report_user_rec_t *dup_report_user;

	dup_report_user = (slurmdb_report_user_rec_t *) x;
	if (dup_report_user->tres_list == NULL)
		return 1;
	return 0;
}

/* Return 1 if UID for two user records match */
static int _match_user_acct(void *x, void *key)
{
	slurmdb_report_user_rec_t *orig_report_user;
	slurmdb_report_user_rec_t *dup_report_user;

	orig_report_user = (slurmdb_report_user_rec_t *) key;
	dup_report_user  = (slurmdb_report_user_rec_t *) x;
	if ((orig_report_user->uid == dup_report_user->uid) &&
	    !xstrcmp(orig_report_user->acct, dup_report_user->acct))
		return 1;
	return 0;
}

/* For duplicate user/account records, combine TRES records into the original
 * list and purge the duplicate records */
extern void combine_user_tres(list_t *first_user_list, list_t *new_user_list)
{
	slurmdb_report_user_rec_t *orig_report_user = NULL;
	slurmdb_report_user_rec_t *dup_report_user = NULL;
	list_itr_t *iter = NULL;

	if (!first_user_list || !new_user_list)
		return;

	iter = list_iterator_create(first_user_list);
	while ((orig_report_user = list_next(iter))) {
		dup_report_user = list_find_first(new_user_list,
						  _match_user_acct,
						  orig_report_user);
		if (!dup_report_user)
			continue;
		combine_tres_list(orig_report_user->tres_list,
				  dup_report_user->tres_list);
		FREE_NULL_LIST(dup_report_user->tres_list);
	}
	list_iterator_destroy(iter);

	(void) list_delete_all(new_user_list, _find_empty_user_tres, NULL);
	list_transfer(first_user_list, new_user_list);
}

extern void common_get_qos_list(void)
{
	slurmdb_qos_cond_t qos_cond = {
		.flags = QOS_COND_FLAG_WITH_DELETED,
	};
	if (g_qos_list)
		return;
	g_qos_list = slurmdb_qos_get(db_conn, &qos_cond);
}
