/****************************************************************************\
 *  opts.c - sbcast command line option processing functions
 *****************************************************************************
 *  Copyright (C) 2006-2007 The Regents of the University of California.
 *  Copyright (C) 2008 Lawrence Livermore National Security.
 *  Copyright (C) SchedMD LLC.
 *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
 *  Written by Morris Jette <jette1@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 "config.h"

#define _GNU_SOURCE

#include <getopt.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "src/common/proc_args.h"
#include "src/common/read_config.h"
#include "src/common/xmalloc.h"
#include "src/common/xstring.h"

#include "src/sbcast/sbcast.h"

#define OPT_LONG_EXCLUDE   0x100
#define OPT_LONG_HELP      0x101
#define OPT_LONG_USAGE     0x102
#define OPT_LONG_SEND_LIBS 0x103
#define OPT_LONG_AUTOCOMP  0x104
#define OPT_LONG_TREE_WIDTH 0x105


/* getopt_long options, integers but not characters */

/* FUNCTIONS */
static void _fill_in_selected_step_from_controller();
static void _fill_in_selected_step_from_env(void);
static void _fill_in_selected_steps_from_env(char *het_size_str);
static void     _help( void );
static bool _need_hetjob_components(job_info_msg_t **job_info_msg);
static uint32_t _map_size( char *buf );
static void     _print_options( void );
static void     _usage( void );

static bool _need_hetjob_components(job_info_msg_t **job_info_msg)
{
	slurm_job_info_t *jobs = NULL;
	int rc;

	/* If <jobid>+<offset> specified we target single component. */
	if (params.selected_step->het_job_offset != NO_VAL)
		return false;

	if (!job_info_msg) {
		error("job_info_msg pointer is NULL before calling slurm_load_job().");
		exit(1);
	}

	if ((rc = slurm_load_job(job_info_msg,
				 params.selected_step->step_id.job_id,
				 SHOW_ALL)) != SLURM_SUCCESS) {
		error("Failed to load JobId=%u: '%s'",
		      params.selected_step->step_id.job_id,
		      slurm_strerror(rc));
		exit(1);
	} else if (!*job_info_msg || (((*job_info_msg)->record_count) <= 0)) {
		error("Failed to load JobId=%u: No jobs returned.",
		      params.selected_step->step_id.job_id);
		exit(1);
	}

	jobs = (*job_info_msg)->job_array;

	if (jobs->job_id != jobs->het_job_id)
		return false;

	if ((*job_info_msg)->record_count < 2)
		fatal("slurm_load_job(%u) returned less than 2 records",
		      params.selected_step->step_id.job_id);

	/* <jobid> without +<offset> and its HetJob leader */
	return true;
}

static void _fill_in_selected_step_from_controller()
{
	job_info_msg_t *job_info_msg = NULL;
	slurm_job_info_t *job = NULL;
	char *job_id_str = NULL;

	if (!_need_hetjob_components(&job_info_msg))
		return;

	job = job_info_msg->job_array;
	params.selected_steps = list_create(slurm_destroy_selected_step);

	for (int i = 0; i < job_info_msg->record_count; i++, job++) {
		job_id_str = xstrdup_printf("%u+%u", job->het_job_id,
					    job->het_job_offset);
		list_append(params.selected_steps,
			    slurm_parse_step_str(job_id_str));
		xfree(job_id_str);
	}

	xassert(list_count(params.selected_steps) >= 2);
}

static void _fill_in_selected_steps_from_env(char *het_size_str)
{
	char *name = NULL, *job_id_str = NULL;
	uint32_t het_size;

	if (parse_uint32(het_size_str, &het_size) || (het_size < 2))
		fatal("Invalid environment SLURM_HET_SIZE value: %s",
		      het_size_str);

	params.selected_steps = list_create(slurm_destroy_selected_step);

	for (int i = 0; i < het_size; i++) {
		name = xstrdup_printf("SLURM_JOB_ID_HET_GROUP_%d", i);
		if (!(job_id_str = getenv(name)))
			fatal("getenv(%s) returned NULL", name);
		xfree(name);
		list_append(params.selected_steps,
			    slurm_parse_step_str(job_id_str));
	}
}

static void _fill_in_selected_step_from_env(void)
{
	char *env_val = NULL;

	if ((env_val = getenv("SLURM_HET_SIZE"))) {
		_fill_in_selected_steps_from_env(env_val);
		return;
	}

	if (!(env_val = getenv("SLURM_JOB_ID"))) {
		error("Need a job id to run this command.  "
		      "Run from within a Slurm job or use the "
		      "--jobid option.");
		exit(1);
	}
	slurm_destroy_selected_step(params.selected_step);
	params.selected_step = slurm_parse_step_str(env_val);
}

/*
 * parse_command_line, fill in params data structure with data
 */
extern void parse_command_line(int argc, char **argv)
{
	char *env_val = NULL, *tmp;
	int opt_char, ret;
	int option_index;
	static struct option long_options[] = {
		{"autocomplete", required_argument, 0, OPT_LONG_AUTOCOMP},
		{"compress",  optional_argument, 0, 'C'},
		{"exclude",   required_argument, 0, OPT_LONG_EXCLUDE},
		{"fanout",    required_argument, 0, 'F'},
		{"treewidth",    required_argument, 0, OPT_LONG_TREE_WIDTH},
		{"force",     no_argument,       0, 'f'},
		{"jobid",     required_argument, 0, 'j'},
		{"no-allocation", optional_argument, 0, 'Z'},
		{"nodelist",  optional_argument, 0, 'w'},
		{"send-libs", optional_argument, 0, OPT_LONG_SEND_LIBS},
		{"preserve",  no_argument,       0, 'p'},
		{"size",      required_argument, 0, 's'},
		{"timeout",   required_argument, 0, 't'},
		{"verbose",   no_argument,       0, 'v'},
		{"version",   no_argument,       0, 'V'},
		{"help",      no_argument,       0, OPT_LONG_HELP},
		{"usage",     no_argument,       0, OPT_LONG_USAGE},
		{NULL,        0,                 0, 0}
	};

	if ((tmp = conf_get_opt_str(slurm_conf.bcast_parameters,
				    "Compression="))) {
		params.compress = parse_compress_type(tmp);
		xfree(tmp);
	}

	if (slurm_conf.bcast_exclude)
		params.exclude = xstrdup(slurm_conf.bcast_exclude);

	if ((env_val = getenv("SBCAST_COMPRESS")))
		params.compress = parse_compress_type(env_val);
	if ((env_val = getenv("SBCAST_EXCLUDE"))) {
		xfree(params.exclude);
		params.exclude = xstrdup(env_val);
	}
	if ((env_val = getenv("SBCAST_TREE_WIDTH")) ||
	    (env_val = getenv("SBCAST_FANOUT"))) {
		if (!xstrcasecmp(env_val, "off"))
			params.tree_width = 0xfffd;
		else
			params.tree_width = atoi(env_val);
	}
	if (getenv("SBCAST_FORCE"))
		params.flags |= BCAST_FLAG_FORCE;

	if (getenv("SBCAST_PRESERVE"))
		params.flags |= BCAST_FLAG_PRESERVE;

	if (xstrcasestr(slurm_conf.bcast_parameters, "send_libs"))
		params.flags |= BCAST_FLAG_SEND_LIBS;

	if ((env_val = getenv("SBCAST_SEND_LIBS"))) {
		ret = parse_send_libs(env_val);
		if (ret == -1)
			error("Ignoring unrecognized SBCAST_SEND_LIBS value '%s'",
			      env_val);
		else if (ret)
			params.flags |= BCAST_FLAG_SEND_LIBS;
		else
			params.flags &= ~BCAST_FLAG_SEND_LIBS;
	}

	if ( ( env_val = getenv("SBCAST_SIZE") ) )
		params.block_size = _map_size(env_val);
	else
		params.block_size = 8 * 1024 * 1024;
	if ( ( env_val = getenv("SBCAST_TIMEOUT") ) )
		params.timeout = (atoi(env_val) * 1000);

	optind = 0;
	while ((opt_char = getopt_long(argc, argv, "C::fF:j:ps:t:vVw:Z",
			long_options, &option_index)) != -1) {
		switch (opt_char) {
		case (int)'?':
			fprintf(stderr,
				"Try \"sbcast --help\" for more information\n");
			exit(1);
			break;
		case (int)'C':
			params.compress = parse_compress_type(optarg);
			break;
		case (int) OPT_LONG_EXCLUDE:
			xfree(params.exclude);
			params.exclude = xstrdup(optarg);
			break;
		case (int)'f':
			params.flags |= BCAST_FLAG_FORCE;
			break;
		case OPT_LONG_TREE_WIDTH:
		case (int)'F':
			if (!xstrcasecmp(optarg, "off"))
				params.tree_width = 0xfffd;
			else
				params.tree_width = atoi(optarg);
			break;
		case (int)'j':
			params.selected_step = slurm_parse_step_str(optarg);
			break;
		case (int)'p':
			params.flags |= BCAST_FLAG_PRESERVE;
			break;
		case (int) OPT_LONG_SEND_LIBS:
			ret = parse_send_libs(optarg);
			if (ret == -1)
				error("Ignoring unrecognized --send-libs value '%s'",
				      optarg);
			else if (ret)
				params.flags |= BCAST_FLAG_SEND_LIBS;
			else if (params.flags & BCAST_FLAG_SEND_LIBS)
				params.flags &= ~BCAST_FLAG_SEND_LIBS;
			break;
		case (int) 's':
			params.block_size = _map_size(optarg);
			break;
		case (int)'t':
			params.timeout = (atoi(optarg) * 1000);
			break;
		case (int) 'v':
			params.verbose++;
			break;
		case (int) 'V':
			print_slurm_version();
			exit(0);
		case (int) 'w':
			xfree(params.node_list);
			params.node_list = xstrdup(optarg);
			break;
		case (int) 'Z':
			params.flags |= BCAST_FLAG_NO_JOB;
			break;
		case (int) OPT_LONG_HELP:
			_help();
			exit(0);
		case (int) OPT_LONG_USAGE:
			_usage();
			exit(0);
		case OPT_LONG_AUTOCOMP:
			suggest_completion(long_options, optarg);
			exit(0);
			break;
		}
	}

	if ((argc - optind) != 2) {
		fprintf(stderr, "Need two file names, have %d names\n",
			(argc - optind));
		fprintf(stderr, "Try \"sbcast --help\" for more information\n");
		exit(1);
	}

	if ((!params.selected_step ||
	     (params.selected_step->step_id.job_id == NO_VAL)) &&
	    !(params.flags & BCAST_FLAG_NO_JOB)) {
		_fill_in_selected_step_from_env();
	} else if ((params.selected_step &&
		    params.selected_step->step_id.job_id != NO_VAL) &&
		   !(params.flags & BCAST_FLAG_NO_JOB)) {
		_fill_in_selected_step_from_controller();
	}

	params.src_fname = xstrdup(argv[optind]);

	if (argv[optind+1][0] == '/') {
		params.dst_fname = xstrdup(argv[optind+1]);
	} else if ((params.dst_fname =
		    conf_get_opt_str(slurm_conf.bcast_parameters,
				     "DestDir="))) {
		xstrfmtcat(params.dst_fname, "/%s", argv[optind+1]);
	} else {
#ifdef HAVE_GET_CURRENT_DIR_NAME
		tmp = get_current_dir_name();
#else
		tmp = malloc(PATH_MAX);
		tmp = getcwd(tmp, PATH_MAX);
#endif
		xstrfmtcat(params.dst_fname, "%s/%s", tmp, argv[optind+1]);
		free(tmp);
	}

	if (params.dst_fname[strlen(params.dst_fname) - 1] == '/') {
		error("Target filename cannot be a directory.");
		exit(1);
	}

	if ((params.flags & BCAST_FLAG_NO_JOB) && (params.selected_step)) {
		error("--no-allocation/-Z and --jobid/-j options are mutually exclusive");
		exit(1);
	}

	if ((params.flags & BCAST_FLAG_NO_JOB) && (!params.node_list)) {
		error("--nodelist/-w is required with --no-allocation/-Z.");
		exit(1);
	}

	if (params.verbose)
		_print_options();
}

/* map size in string to number, interpret suffix of "k" or "m" */
static uint32_t _map_size( char *buf )
{
	long b_size;
	char *end_ptr;

	b_size = strtol(buf, &end_ptr, 10);
	if ((b_size == LONG_MIN) || (b_size == LONG_MAX) || (b_size < 0)) {
		fprintf(stderr, "size specification is invalid, ignored\n");
		b_size = 0;
	} else if (end_ptr[0] == '\0')
		;
	else if ((end_ptr[0] == 'k') || (end_ptr[0] == 'K'))
		b_size *= 1024;
	else if ((end_ptr[0] == 'm') || (end_ptr[0] == 'M'))
		b_size *= (1024 * 1024);
	else {
		fprintf(stderr, "size specification is invalid, ignored\n");
		b_size = 0;
	}
	return (uint32_t) b_size;
}

/* print the parameters specified */
static void _print_options( void )
{
	info("-----------------------------");
	info("block_size = %u", params.block_size);
	info("compress   = %u", params.compress);
	info("exclude    = %s", params.exclude);
	info("force      = %s",
	     (params.flags & BCAST_FLAG_FORCE) ? "true" : "false");
	info("treewidth     = %d", params.tree_width);
	info("preserve   = %s",
	     (params.flags & BCAST_FLAG_PRESERVE) ? "true" : "false");
	info("send_libs  = %s",
	     (params.flags & BCAST_FLAG_SEND_LIBS) ? "true" : "false");
	info("timeout    = %d", params.timeout);
	info("verbose    = %d", params.verbose);
	info("source     = %s", params.src_fname);
	info("dest       = %s", params.dst_fname);
	info("-----------------------------");
}


static void _usage( void )
{
	printf("Usage: sbcast [--exclude] [-CfFjpvV] [--send-libs] SOURCE DEST\n");
}

static void _help( void )
{
	printf ("\
Usage: sbcast [OPTIONS] SOURCE DEST\n\
  -C, --compress[=lib]  compress the file being transmitted\n\
  --exclude=<path_list> shared object paths to be excluded\n\
  -f, --force           replace destination file as required\n\
  --treewidth=num       specify message treewidth\n\
  -j, --jobid=#[+#][.#] specify job ID with optional hetjob offset and/or step ID\n\
  -p, --preserve        preserve modes and times of source file\n\
  --send-libs[=yes|no]  autodetect and broadcast executable's shared objects\n\
  -s, --size=num        block size in bytes (rounded off)\n\
  -t, --timeout=secs    specify message timeout (seconds)\n\
  -v, --verbose         provide detailed event logging\n\
  -V, --version         print version information and exit\n\
\nHelp options:\n\
  --help                show this help message\n\
  --usage               display brief usage message\n");
}
