/*****************************************************************************\
 *  cron.c
 *****************************************************************************
 *  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 <ctype.h>
#include <unistd.h>

#include "src/common/bitstring.h"
#include "src/common/cron.h"
#include "src/common/log.h"
#include "src/common/pack.h"
#include "src/common/read_config.h"
#include "src/common/slurm_time.h"
#include "src/common/uid.h"
#include "src/common/xmalloc.h"
#include "src/common/xstring.h"

#define LEAP_YEAR(y) ((y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0))

extern cron_entry_t *new_cron_entry(void)
{
	cron_entry_t *entry = xmalloc(sizeof(*entry));

	entry->minute = bit_alloc(61);
	entry->hour = bit_alloc(25);
	entry->day_of_month = bit_alloc(32);
	entry->month = bit_alloc(13);
	entry->day_of_week = bit_alloc(8);

	return entry;
}

extern void free_cron_entry(void *in)
{
	cron_entry_t *entry = (cron_entry_t *) in;

	if (!entry)
		return;

	xfree(entry->minute);
	xfree(entry->hour);
	xfree(entry->day_of_month);
	xfree(entry->month);
	xfree(entry->day_of_week);
	xfree(entry->cronspec);
	xfree(entry->command);
	xfree(entry);
}

extern bool valid_cron_entry(cron_entry_t *e)
{
	int first_day_of_month;

	/* basic structure check */
	if ((bit_size(e->minute) != 61) ||
	    (bit_size(e->hour) != 25) ||
	    (bit_size(e->day_of_month) != 32) ||
	    (bit_size(e->month) != 13) ||
	    (bit_size(e->day_of_week) != 8))
		return false;

	/*
	 * Clear top or lower bits (may have been set for wildcard processing).
	 */
	bit_clear(e->minute, 60);
	bit_clear(e->hour, 24);
	bit_clear(e->day_of_month, 0);
	bit_clear(e->month, 0);
	bit_clear(e->day_of_week, 7);

	/*
	 * Missing some e. Need at least one bit set in each field or
	 * the wildcard flag, otherwise calc_next_cron_start() will break.
	 */
	first_day_of_month = bit_ffs(e->day_of_month);
	if ((!(e->flags & CRON_WILD_MINUTE) && (bit_ffs(e->minute) == -1)) ||
	    (!(e->flags & CRON_WILD_HOUR) && (bit_ffs(e->hour) == -1)) ||
	    (!(e->flags & CRON_WILD_DOM) && (first_day_of_month == -1)) ||
	    (!(e->flags & CRON_WILD_MONTH) && (bit_ffs(e->month) == -1)) ||
	    (!(e->flags & CRON_WILD_DOW) && (bit_ffs(e->day_of_week) == -1)))
		return false;

	/*
	 * Make sure the crontab isn't requesting a non-existent
	 * combination of month and day.
	 *
	 * Note: we do allow you to schedule something to only run
	 * on leap days, as crazy as that may seem.
	 */
	if (e->flags & CRON_WILD_DOM) {
		;
	} else if (first_day_of_month == 31) {
		if (!bit_test(e->month, 1) && !bit_test(e->month, 3) &&
		    !bit_test(e->month, 5) && !bit_test(e->month, 7) &&
		    !bit_test(e->month, 8) && !bit_test(e->month, 10) &&
		    !bit_test(e->month, 12))
			return false;
	} else if (first_day_of_month == 30) {
		/* Make sure the only month available isn't February. */
		if ((bit_fls(e->month) == 2) && (bit_ffs(e->month) == 2))
			return false;
	}

	return true;
}

extern char *cronspec_from_cron_entry(cron_entry_t *entry)
{
	char *cronspec = NULL;
	char *fmt;

	if (entry->flags & CRON_WILD_MINUTE) {
		xstrcat(cronspec, "* ");
	} else {
		fmt = bit_fmt_full(entry->minute);
		xstrfmtcat(cronspec, "%s ", fmt);
		xfree(fmt);
	}

	if (entry->flags & CRON_WILD_HOUR) {
		xstrcat(cronspec, "* ");
	} else {
		fmt = bit_fmt_full(entry->hour);
		xstrfmtcat(cronspec, "%s ", fmt);
		xfree(fmt);
	}

	if (entry->flags & CRON_WILD_DOM) {
		xstrcat(cronspec, "* ");
	} else {
		fmt = bit_fmt_full(entry->day_of_month);
		xstrfmtcat(cronspec, "%s ", fmt);
		xfree(fmt);
	}

	if (entry->flags & CRON_WILD_MONTH) {
		xstrcat(cronspec, "* ");
	} else {
		fmt = bit_fmt_full(entry->month);
		xstrfmtcat(cronspec, "%s ", fmt);
		xfree(fmt);
	}

	if (entry->flags & CRON_WILD_DOW) {
		xstrcat(cronspec, "*");
	} else {
		fmt = bit_fmt_full(entry->day_of_week);
		xstrfmtcat(cronspec, "%s", fmt);
		xfree(fmt);
	}

	return cronspec;
}

/*
 * Determine how many months there are between now and the next month this job
 * could run in.
 *
 * One important note: struct tm has jan == 0, but the crontab
 * format and our bitstring have jan == 1.
 */
static int _next_month(cron_entry_t *entry, struct tm *tm)
{
	int months_to_advance = 0;

	/* tm_mon should be 0-11 */
	xassert(tm->tm_mon >= 0);
	xassert(tm->tm_mon <= 11);

	/* month is current valid, nice and easy, no major adjustments needed */
	if (entry->flags & CRON_WILD_MONTH ||
	    bit_test(entry->month, tm->tm_mon + 1))
		return 0;

	/* Start testing from now to get the closest month */
	for (int i = tm->tm_mon; i < 12; i++) {
		if (bit_test(entry->month, i + 1))
			goto found;
		months_to_advance++;
	}

	/* Loop around to beginning of the year if needed */
	for (int i = 0; i < tm->tm_mon; i++) {
		if (bit_test(entry->month, i + 1))
			goto found;
		months_to_advance++;
	}

	fatal("Could not find a valid month, this should be impossible");

found:
	/*
	 * Next usable month is not this month. Reset other timing to midnight
	 * on the first of the next valid month.
	 */
	tm->tm_mon += months_to_advance;
	tm->tm_hour = 0;
	tm->tm_min = 0;
	tm->tm_mday = 1;
	slurm_mktime(tm);

	return 0;
}

/*
 * Determine how many days there are between now and the next day of the week
 * this job could run on.
 *
 * Intended for use when day of week is specified in the cron entry.
 */
static int _next_day_of_week(cron_entry_t *entry, struct tm *tm)
{
	int days_to_advance = 0;

	/* tm_wday should be 0-6 */
	xassert(tm->tm_wday >= 0);
	xassert(tm->tm_wday <= 6);

	/* Start testing from now to get the closest day */
	for (int i = tm->tm_wday; i < 7; i++) {
		if (bit_test(entry->day_of_week, i))
			return days_to_advance;
		days_to_advance++;
	}

	/* Loop around to beginning of the week if needed */
	for (int i = 0; i < tm->tm_wday; i++) {
		if (bit_test(entry->day_of_week, i))
			return days_to_advance;
		days_to_advance++;
	}

	return 0;
}

/* Return number of days in a given tm->tm_mon */
static int _days_in_month(struct tm *tm)
{
	/* Default to maximum days in month (highest likelihood) */
	int days_in_month = 31;

	/* tm_mon should be 0-11 */
	xassert(tm->tm_mon >= 0);
	xassert(tm->tm_mon <= 11);

	switch (tm->tm_mon) {
	case 1:
		days_in_month = LEAP_YEAR(tm->tm_year) ? 29 : 28;
		break;
	case 3:
	case 5:
	case 8:
	case 10:
		days_in_month = 30;
		break;
	}

	return days_in_month;
}

/*
 * Determine how many days there are between now and the next day of the month
 * this job could run on.
 *
 * Intended for use when day of month is specified in the cron entry.
 */
static int _next_day_of_month(cron_entry_t *entry, struct tm *tm)
{
	int days_to_advance = 0;
	int days_in_month;

	/* tm_mday should be 1-31 */
	xassert(tm->tm_mday >= 1);
	xassert(tm->tm_mday <= 31);

	days_in_month = _days_in_month(tm);

	/*
	 * Advance days within tm month till cron entry day found (and return
	 * count) or reach days in tm month.
	 */
	for (int i = tm->tm_mday; i <= days_in_month; i++) {
		if (bit_test(entry->day_of_month, i))
			return days_to_advance;
		days_to_advance++;
	}

	/*
	 * Continue advancing days within next month till tm_mday found and return
	 * aggregated count of advanced days.
	 */
	for (int i = 1; i < tm->tm_mday; i++) {
		if (bit_test(entry->day_of_month, i))
			return days_to_advance;
		days_to_advance++;
	}

	return days_to_advance;
}

extern time_t calc_next_cron_start(cron_entry_t *entry, time_t next)
{
	struct tm tm;
	time_t now = time(NULL);
	int validated_month, days_to_add;

	/*
	 * Avoid running twice in the same minute.
	 */
	if (next && next > now + 60) {
		now = next;
		localtime_r(&now, &tm);
		tm.tm_sec = 0;
	} else {
		localtime_r(&now, &tm);
		tm.tm_sec = 0;
		tm.tm_min++;
	}

month:
	_next_month(entry, &tm);

	validated_month = tm.tm_mon;

	days_to_add = 0;
	if ((entry->flags & CRON_WILD_DOM) && (entry->flags & CRON_WILD_DOW)) {
		/* Wildcard for both is the easy path out. */
		;
	} else if (entry->flags & CRON_WILD_DOM) {
		/*
		 * Only pay attention to the day of week.
		 */
		days_to_add = _next_day_of_week(entry, &tm);
	} else if (entry->flags & CRON_WILD_DOW) {
		/*
		 * Only attention to the day of month.
		 */
		days_to_add = _next_day_of_month(entry, &tm);
	} else {
		/*
		 * When both are specified, the defacto behavior is to
		 * treat them as OR'd rather than AND'd, as trying to
		 * resolve both simultaneously would result in the job
		 * very rarely running.
		 * So find the soonest time between them and use that.
		 */
		int dom_next = _next_day_of_month(entry, &tm);
		int dow_next = _next_day_of_week(entry, &tm);

		days_to_add = MIN(dom_next, dow_next);
	}
	if (days_to_add) {
		tm.tm_mday += days_to_add;
		tm.tm_hour = 0;
		tm.tm_min = 0;
		slurm_mktime(&tm);

		/* month slipped back, need to re-validate */
		if (validated_month != tm.tm_mon)
			goto month;
	}

hour:
	if (!(entry->flags & CRON_WILD_HOUR) &&
	    !bit_test(entry->hour, tm.tm_hour)) {
		/* must be in future, reset minutes */
		tm.tm_min = 0;

		while (tm.tm_hour < 24) {
			if (bit_test(entry->hour, tm.tm_hour))
				break;
			tm.tm_hour++;
		}
		if (tm.tm_hour == 24) {
			/*
			 * tm_hour set to 24 rolls the day and possibly
			 * the month at well. revalidate month + day.
			 */
			slurm_mktime(&tm);
			goto month;
		}
	}

	if (!(entry->flags & CRON_WILD_MINUTE) &&
	    !bit_test(entry->minute, tm.tm_min)) {
		while (tm.tm_min < 60) {
			if (bit_test(entry->minute, tm.tm_min))
				break;
			tm.tm_min++;
		}
		if (tm.tm_min == 60 && tm.tm_hour == 23) {
			/*
			 * this will roll into the next day,
			 * which may also be a new month
			 */
			slurm_mktime(&tm);
			goto month;
		} else if (tm.tm_min == 60) {
			/*
			 * next hour, but fortunately still
			 * in the same day
			 */
			tm.tm_min = 0;
			tm.tm_hour++;
			goto hour;
		}
	}

	return slurm_mktime(&tm);
}

extern void pack_cron_entry(void *in, uint16_t protocol_version,
			    buf_t *buffer)
{
	uint8_t set = (in ? 1 : 0);
	cron_entry_t *entry = (cron_entry_t *) in;

	pack8(set, buffer);

	if (!set)
		return;

	if (protocol_version >= SLURM_MIN_PROTOCOL_VERSION) {
		pack32(entry->flags, buffer);
		pack_bit_str_hex(entry->minute, buffer);
		pack_bit_str_hex(entry->hour, buffer);
		pack_bit_str_hex(entry->day_of_month, buffer);
		pack_bit_str_hex(entry->month, buffer);
		pack_bit_str_hex(entry->day_of_week, buffer);
		packstr(entry->cronspec, buffer);
		/* command is not packed, only in struct for parsing */
		pack32(entry->line_start, buffer);
		pack32(entry->line_end, buffer);
	}
}

extern int unpack_cron_entry(void **entry_ptr, uint16_t protocol_version,
			     buf_t *buffer)
{
	uint8_t set;
	cron_entry_t *entry = NULL;

	xassert(entry_ptr);

	safe_unpack8(&set, buffer);

	if (!set)
		return SLURM_SUCCESS;

	entry = xmalloc(sizeof(*entry));
	*entry_ptr = entry;

	if (protocol_version >= SLURM_MIN_PROTOCOL_VERSION) {
		safe_unpack32(&entry->flags, buffer);
		unpack_bit_str_hex(&entry->minute, buffer);
		unpack_bit_str_hex(&entry->hour, buffer);
		unpack_bit_str_hex(&entry->day_of_month, buffer);
		unpack_bit_str_hex(&entry->month, buffer);
		unpack_bit_str_hex(&entry->day_of_week, buffer);
		safe_unpackstr(&entry->cronspec, buffer);
		/* command is not packed, only in struct for parsing */
		safe_unpack32(&entry->line_start, buffer);
		safe_unpack32(&entry->line_end, buffer);
	} else {
		goto unpack_error;
	}

	return SLURM_SUCCESS;

unpack_error:
	*entry_ptr = NULL;
	free_cron_entry(entry);
	return SLURM_ERROR;
}
