/*****************************************************************************\
 *  job_functions.c - Functions related to job display mode of smap.
 *****************************************************************************
 *  Copyright (C) 2002-2007 The Regents of the University of California.
 *  Copyright (C) 2008-2011 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 <http://www.schedmd.com/slurmdocs/>.
 *  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/common/uid.h"
#include "src/common/node_select.h"
#include "src/common/parse_time.h"
#include "src/smap/smap.h"

static int  _get_node_cnt(job_info_t * job);
static int  _max_cpus_per_node(void);
static int  _nodes_in_list(char *node_list);
static void _print_header_job(void);
static int  _print_text_job(job_info_t * job_ptr);

extern void get_job(void)
{
	int error_code = -1, i, recs;
	static int printed_jobs = 0;
	static int count = 0;
	static job_info_msg_t *job_info_ptr = NULL, *new_job_ptr = NULL;
	job_info_t *job_ptr = NULL;
	uint16_t show_flags = 0;
	bitstr_t *nodes_req = NULL;
	static uint16_t last_flags = 0;

	if (params.all_flag)
		show_flags |= SHOW_ALL;
	if (job_info_ptr) {
		if (show_flags != last_flags)
			job_info_ptr->last_update = 0;
		error_code = slurm_load_jobs(job_info_ptr->last_update,
					     &new_job_ptr, show_flags);
		if (error_code == SLURM_SUCCESS)
			slurm_free_job_info_msg(job_info_ptr);
		else if (slurm_get_errno() == SLURM_NO_CHANGE_IN_DATA) {
			error_code = SLURM_SUCCESS;
			new_job_ptr = job_info_ptr;
		}
	} else
		error_code = slurm_load_jobs((time_t) NULL, &new_job_ptr,
					     show_flags);

	last_flags = show_flags;
	if (error_code) {
		if (quiet_flag != 1) {
			if (!params.commandline) {
				mvwprintw(text_win,
					  main_ycord, 1,
					  "slurm_load_job: %s",
					  slurm_strerror(slurm_get_errno()));
				main_ycord++;
			} else {
				printf("slurm_load_job: %s\n",
				       slurm_strerror(slurm_get_errno()));
			}
		}
	}

	if (!params.no_header)
		_print_header_job();

	if (new_job_ptr)
		recs = new_job_ptr->record_count;
	else
		recs = 0;

	if (!params.commandline)
		if ((text_line_cnt+printed_jobs) > count)
			text_line_cnt--;
	printed_jobs = 0;
	count = 0;

	if (params.hl)
		nodes_req = get_requested_node_bitmap();
	for (i = 0; i < recs; i++) {
		job_ptr = &(new_job_ptr->job_array[i]);
		if (!IS_JOB_PENDING(job_ptr)   && !IS_JOB_RUNNING(job_ptr) &&
		    !IS_JOB_SUSPENDED(job_ptr) && !IS_JOB_COMPLETING(job_ptr))
			continue;	/* job has completed */
		if (nodes_req) {
			int overlap = 0;
			bitstr_t *loc_bitmap = bit_alloc(bit_size(nodes_req));
			inx2bitstr(loc_bitmap, job_ptr->node_inx);
			overlap = bit_overlap(loc_bitmap, nodes_req);
			FREE_NULL_BITMAP(loc_bitmap);
			if (!overlap)
				continue;
		}

		if (job_ptr->node_inx[0] != -1) {
			int j = 0;
			job_ptr->num_nodes = 0;
			while (job_ptr->node_inx[j] >= 0) {
				job_ptr->num_nodes +=
					(job_ptr->node_inx[j + 1] + 1) -
					 job_ptr->node_inx[j];
				set_grid_inx(job_ptr->node_inx[j],
					     job_ptr->node_inx[j + 1], count);
				j += 2;
			}

			if (!params.commandline) {
				if ((count >= text_line_cnt) &&
				    (printed_jobs < (getmaxy(text_win) - 4))) {
					job_ptr->num_cpus =
						(int)letters[count%62];
					wattron(text_win,
						COLOR_PAIR(colors[count%6]));
					_print_text_job(job_ptr);
					wattroff(text_win,
						 COLOR_PAIR(colors[count%6]));
					printed_jobs++;
				}
			} else {
				job_ptr->num_cpus = (int)letters[count%62];
				_print_text_job(job_ptr);
			}
			count++;
		}
		if (count == 128)
			count = 0;
	}

	for (i = 0; i < recs; i++) {
		job_ptr = &(new_job_ptr->job_array[i]);

		if (!IS_JOB_PENDING(job_ptr))
			continue;	/* job has completed */

		if (!params.commandline) {
			if ((count>=text_line_cnt) &&
			    (printed_jobs < (getmaxy(text_win) - 4))) {
				xfree(job_ptr->nodes);
				job_ptr->nodes = xstrdup("waiting...");
				job_ptr->num_cpus = (int) letters[count%62];
				wattron(text_win,
					COLOR_PAIR(colors[count%6]));
				_print_text_job(job_ptr);
				wattroff(text_win,
					 COLOR_PAIR(colors[count%6]));
				printed_jobs++;
			}
		} else {
			xfree(job_ptr->nodes);
			job_ptr->nodes = xstrdup("waiting...");
			job_ptr->num_cpus = (int) letters[count%62];
			_print_text_job(job_ptr);
			printed_jobs++;
		}
		count++;

		if (count == 128)
			count = 0;
	}

	if (params.commandline && params.iterate)
		printf("\n");

	if (!params.commandline)
		main_ycord++;

	job_info_ptr = new_job_ptr;
	return;
}

static void _print_header_job(void)
{
	if (!params.commandline) {
		mvwprintw(text_win, main_ycord,
			  main_xcord, "ID");
		main_xcord += 3;
		mvwprintw(text_win, main_ycord,
			  main_xcord, "JOBID");
		main_xcord += 8;
		mvwprintw(text_win, main_ycord,
			  main_xcord, "PARTITION");
		main_xcord += 10;
		if (params.cluster_flags & CLUSTER_FLAG_BG) {
			mvwprintw(text_win, main_ycord,
				  main_xcord, "BG_BLOCK");
			main_xcord += 18;
		}
		if (params.cluster_flags & CLUSTER_FLAG_CRAYXT) {
			mvwprintw(text_win, main_ycord,
				  main_xcord, "RESV_ID");
			main_xcord += 18;
		}
		mvwprintw(text_win, main_ycord,
			  main_xcord, "USER");
		main_xcord += 9;
		mvwprintw(text_win, main_ycord,
			  main_xcord, "NAME");
		main_xcord += 10;
		mvwprintw(text_win, main_ycord,
			  main_xcord, "ST");
		main_xcord += 8;
		mvwprintw(text_win, main_ycord,
			  main_xcord, "TIME");
		main_xcord += 5;
		mvwprintw(text_win, main_ycord,
			  main_xcord, "NODES");
		main_xcord += 6;
		if (params.cluster_flags & CLUSTER_FLAG_BG)
			mvwprintw(text_win, main_ycord,
				  main_xcord, "MIDPLANELIST");
		else
			mvwprintw(text_win, main_ycord,
				  main_xcord, "NODELIST");
		main_xcord = 1;
		main_ycord++;
	} else {
		printf("   JOBID ");
		printf("PARTITION ");
		if (params.cluster_flags & CLUSTER_FLAG_BG)
			printf("        BG_BLOCK ");
		printf("    USER ");
		printf("  NAME ");
		printf("ST ");
		printf("      TIME ");
		printf("NODES ");
		if (params.cluster_flags & CLUSTER_FLAG_BG)
			printf("MIDPLANELIST\n");
		else
			printf("NODELIST\n");
	}
}
static long _job_time_used(job_info_t * job_ptr)
{
	time_t end_time;

	if ((job_ptr->start_time == 0) || IS_JOB_PENDING(job_ptr))
		return 0L;

	if (IS_JOB_SUSPENDED(job_ptr))
		return (long) job_ptr->pre_sus_time;

	if (IS_JOB_RUNNING(job_ptr) || (job_ptr->end_time == 0))
		end_time = time(NULL);
	else
		end_time = job_ptr->end_time;

	if (job_ptr->suspend_time)
		return (long) (difftime(end_time, job_ptr->suspend_time)
				+ job_ptr->pre_sus_time);
	return (long) (difftime(end_time, job_ptr->start_time));
}

static int _print_text_job(job_info_t * job_ptr)
{
	time_t time_diff;
	int printed = 0;
	int tempxcord;
	int prefixlen = 0;
	int i = 0;
	int width = 0;
	char time_buf[20];
	char tmp_cnt[8];
	uint32_t node_cnt = 0;
	char *ionodes = NULL, *uname;

	if (params.cluster_flags & CLUSTER_FLAG_BG) {
		select_g_select_jobinfo_get(job_ptr->select_jobinfo,
					    SELECT_JOBDATA_IONODES,
					    &ionodes);
		select_g_select_jobinfo_get(job_ptr->select_jobinfo,
					    SELECT_JOBDATA_NODE_CNT,
					    &node_cnt);
		if (!strcasecmp(job_ptr->nodes,"waiting..."))
			xfree(ionodes);
	} else
		node_cnt = job_ptr->num_nodes;

	if ((node_cnt  == 0) || (node_cnt == NO_VAL))
		node_cnt = _get_node_cnt(job_ptr);

	if (params.cluster_flags & CLUSTER_FLAG_BG)
		convert_num_unit((float)node_cnt, tmp_cnt,
				 sizeof(tmp_cnt), UNIT_NONE);
	else
		snprintf(tmp_cnt, sizeof(tmp_cnt), "%d", node_cnt);

	if (!params.commandline) {
		mvwprintw(text_win, main_ycord,
			  main_xcord, "%c", job_ptr->num_cpus);
		main_xcord += 3;
		mvwprintw(text_win, main_ycord,
			  main_xcord, "%d", job_ptr->job_id);
		main_xcord += 8;
		mvwprintw(text_win, main_ycord,
			  main_xcord, "%.10s", job_ptr->partition);
		main_xcord += 10;
		if (params.cluster_flags & CLUSTER_FLAG_BG) {
			mvwprintw(text_win, main_ycord,
				  main_xcord, "%.16s",
				  select_g_select_jobinfo_sprint(
					  job_ptr->select_jobinfo,
					  time_buf,
					  sizeof(time_buf),
					  SELECT_PRINT_BG_ID));
			main_xcord += 18;
		}
		if (params.cluster_flags & CLUSTER_FLAG_CRAYXT) {
			mvwprintw(text_win, main_ycord,
				  main_xcord, "%.16s",
				  select_g_select_jobinfo_sprint(
					  job_ptr->select_jobinfo,
					  time_buf, sizeof(time_buf),
					  SELECT_PRINT_DATA));
			main_xcord += 18;
		}
		uname = uid_to_string((uid_t) job_ptr->user_id);
		mvwprintw(text_win, main_ycord,
			  main_xcord, "%.8s", uname);
		xfree(uname);
		main_xcord += 9;
		mvwprintw(text_win, main_ycord,
			  main_xcord, "%.9s", job_ptr->name);
		main_xcord += 10;
		mvwprintw(text_win, main_ycord,
			  main_xcord, "%.2s",
			  job_state_string_compact(job_ptr->job_state));
		main_xcord += 2;
		if (!strcasecmp(job_ptr->nodes,"waiting...")) {
			sprintf(time_buf,"00:00:00");
		} else {
			time_diff = (time_t) _job_time_used(job_ptr);
			secs2time_str(time_diff, time_buf, sizeof(time_buf));
		}
		width = strlen(time_buf);
		mvwprintw(text_win, main_ycord,
			  main_xcord + (10 - width), "%s",
			  time_buf);
		main_xcord += 11;

		mvwprintw(text_win,
			  main_ycord,
			  main_xcord, "%5s", tmp_cnt);

		main_xcord += 6;

		tempxcord = main_xcord;

		i=0;
		while (job_ptr->nodes[i] != '\0') {
			if ((printed = mvwaddch(text_win,
						main_ycord,
						main_xcord,
						job_ptr->nodes[i])) < 0) {
				xfree(ionodes);
				return printed;
			}
			main_xcord++;
			width = getmaxx(text_win) - 1 - main_xcord;
			if (job_ptr->nodes[i] == '[')
				prefixlen = i + 1;
			else if (job_ptr->nodes[i] == ','
				 && (width - 9) <= 0) {
				main_ycord++;
				main_xcord = tempxcord + prefixlen;
			}
			i++;
		}
		if (ionodes) {
			mvwprintw(text_win,
				  main_ycord,
				  main_xcord, "[%s]",
				  ionodes);
			main_xcord += strlen(ionodes)+2;
			xfree(ionodes);
		}

		main_xcord = 1;
		main_ycord++;
	} else {
		printf("%8d ", job_ptr->job_id);
		printf("%9.9s ", job_ptr->partition);
		if (params.cluster_flags & CLUSTER_FLAG_BG)
			printf("%16.16s ",
			       select_g_select_jobinfo_sprint(
				       job_ptr->select_jobinfo,
				       time_buf, sizeof(time_buf),
				       SELECT_PRINT_BG_ID));
		if (params.cluster_flags & CLUSTER_FLAG_CRAYXT)
			printf("%16.16s ",
			       select_g_select_jobinfo_sprint(
				       job_ptr->select_jobinfo,
				       time_buf, sizeof(time_buf),
				       SELECT_PRINT_DATA));
		uname = uid_to_string((uid_t) job_ptr->user_id);
		printf("%8.8s ", uname);
		xfree(uname);
		printf("%6.6s ", job_ptr->name);
		printf("%2.2s ",
		       job_state_string_compact(job_ptr->job_state));
		if (!strcasecmp(job_ptr->nodes,"waiting...")) {
			sprintf(time_buf,"00:00:00");
		} else {
			time_diff = (time_t) _job_time_used(job_ptr);
			secs2time_str(time_diff, time_buf, sizeof(time_buf));
		}

		printf("%10.10s ", time_buf);

		printf("%5s ", tmp_cnt);

		printf("%s", job_ptr->nodes);
		if (ionodes) {
			printf("[%s]", ionodes);
			xfree(ionodes);
		}

		printf("\n");

	}

	return printed;
}

static int _get_node_cnt(job_info_t * job)
{
	int node_cnt = 0, round;
	bool completing = job->job_state & JOB_COMPLETING;
	uint16_t base_job_state = job->job_state & (~JOB_COMPLETING);
	static int max_cpus = 0;

	if (base_job_state == JOB_PENDING || completing) {
		if (max_cpus == 0)
			max_cpus = _max_cpus_per_node();

		node_cnt = _nodes_in_list(job->req_nodes);
		node_cnt = MAX(node_cnt, job->num_nodes);
		round  = job->num_cpus + max_cpus - 1;
		round /= max_cpus;      /* round up */
		node_cnt = MAX(node_cnt, round);
	} else
		node_cnt = _nodes_in_list(job->nodes);
	return node_cnt;
}

static int _nodes_in_list(char *node_list)
{
	hostset_t host_set = hostset_create(node_list);
	int count = hostset_count(host_set);
	hostset_destroy(host_set);
	return count;
}

/* Return the maximum number of processors for any node in the cluster */
static int   _max_cpus_per_node(void)
{
	int error_code, max_cpus = 1;
	node_info_msg_t *node_info_ptr = NULL;

	error_code = slurm_load_node ((time_t) NULL, &node_info_ptr,
				      params.all_flag ? 1 : 0);
	if (error_code == SLURM_SUCCESS) {
		int i;
		node_info_t *node_ptr = node_info_ptr->node_array;
		for (i=0; i<node_info_ptr->record_count; i++) {
			max_cpus = MAX(max_cpus, node_ptr[i].cpus);
		}
		slurm_free_node_info_msg (node_info_ptr);
	}

	return max_cpus;
}

