///////////////////////////////////////////////////////////////////////////////
//
/// \file       options.c
/// \brief      Parser for filter-specific options
//
//  Author:     Lasse Collin
//
//  This file has been put into the public domain.
//  You can do whatever you want with this file.
//
///////////////////////////////////////////////////////////////////////////////

#include "private.h"


///////////////////
// Generic stuff //
///////////////////

typedef struct {
	const char *name;
	uint64_t id;
} name_id_map;


typedef struct {
	const char *name;
	const name_id_map *map;
	uint64_t min;
	uint64_t max;
} option_map;


/// Parses option=value pairs that are separated with colons, semicolons,
/// or commas: opt=val:opt=val;opt=val,opt=val
///
/// Each option is a string, that is converted to an integer using the
/// index where the option string is in the array.
///
/// Value can be
///  - a string-id map mapping a list of possible string values to integers
///    (opts[i].map != NULL, opts[i].min and opts[i].max are ignored);
///  - a number with minimum and maximum value limit
///    (opts[i].map == NULL && opts[i].min != UINT64_MAX);
///  - a string that will be parsed by the filter-specific code
///    (opts[i].map == NULL && opts[i].min == UINT64_MAX, opts[i].max ignored)
///
/// When parsing both option and value succeed, a filter-specific function
/// is called, which should update the given value to filter-specific
/// options structure.
///
/// \param      str     String containing the options from the command line
/// \param      opts    Filter-specific option map
/// \param      set     Filter-specific function to update filter_options
/// \param      filter_options  Pointer to filter-specific options structure
///
/// \return     Returns only if no errors occur.
///
static void
parse_options(const char *str, const option_map *opts,
		void (*set)(void *filter_options,
			uint32_t key, uint64_t value, const char *valuestr),
		void *filter_options)
{
	if (str == NULL || str[0] == '\0')
		return;

	char *s = xstrdup(str);
	char *name = s;

	while (*name != '\0') {
		if (*name == ',') {
			++name;
			continue;
		}

		char *split = strchr(name, ',');
		if (split != NULL)
			*split = '\0';

		char *value = strchr(name, '=');
		if (value != NULL)
			*value++ = '\0';

		if (value == NULL || value[0] == '\0')
			message_fatal(_("%s: Options must be `name=value' "
					"pairs separated with commas"), str);

		// Look for the option name from the option map.
		size_t i = 0;
		while (true) {
			if (opts[i].name == NULL)
				message_fatal(_("%s: Invalid option name"),
						name);

			if (strcmp(name, opts[i].name) == 0)
				break;

			++i;
		}

		// Option was found from the map. See how we should handle it.
		if (opts[i].map != NULL) {
			// value is a string which we should map
			// to an integer.
			size_t j;
			for (j = 0; opts[i].map[j].name != NULL; ++j) {
				if (strcmp(opts[i].map[j].name, value) == 0)
					break;
			}

			if (opts[i].map[j].name == NULL)
				message_fatal(_("%s: Invalid option value"),
						value);

			set(filter_options, i, opts[i].map[j].id, value);

		} else if (opts[i].min == UINT64_MAX) {
			// value is a special string that will be
			// parsed by set().
			set(filter_options, i, 0, value);

		} else {
			// value is an integer.
			const uint64_t v = str_to_uint64(name, value,
					opts[i].min, opts[i].max);
			set(filter_options, i, v, value);
		}

		// Check if it was the last option.
		if (split == NULL)
			break;

		name = split + 1;
	}

	free(s);
	return;
}


///////////
// Delta //
///////////

enum {
	OPT_DIST,
};


static void
set_delta(void *options, uint32_t key, uint64_t value,
		const char *valuestr lzma_attribute((unused)))
{
	lzma_options_delta *opt = options;
	switch (key) {
	case OPT_DIST:
		opt->dist = value;
		break;
	}
}


extern lzma_options_delta *
options_delta(const char *str)
{
	static const option_map opts[] = {
		{ "dist",     NULL,  LZMA_DELTA_DIST_MIN,
		                     LZMA_DELTA_DIST_MAX },
		{ NULL,       NULL,  0, 0 }
	};

	lzma_options_delta *options = xmalloc(sizeof(lzma_options_delta));
	*options = (lzma_options_delta){
		// It's hard to give a useful default for this.
		.type = LZMA_DELTA_TYPE_BYTE,
		.dist = LZMA_DELTA_DIST_MIN,
	};

	parse_options(str, opts, &set_delta, options);

	return options;
}


/////////
// BCJ //
/////////

enum {
	OPT_START_OFFSET,
};


static void
set_bcj(void *options, uint32_t key, uint64_t value,
		const char *valuestr lzma_attribute((unused)))
{
	lzma_options_bcj *opt = options;
	switch (key) {
	case OPT_START_OFFSET:
		opt->start_offset = value;
		break;
	}
}


extern lzma_options_bcj *
options_bcj(const char *str)
{
	static const option_map opts[] = {
		{ "start",    NULL,  0, UINT32_MAX },
		{ NULL,       NULL,  0, 0 }
	};

	lzma_options_bcj *options = xmalloc(sizeof(lzma_options_bcj));
	*options = (lzma_options_bcj){
		.start_offset = 0,
	};

	parse_options(str, opts, &set_bcj, options);

	return options;
}


//////////
// LZMA //
//////////

enum {
	OPT_PRESET,
	OPT_DICT,
	OPT_LC,
	OPT_LP,
	OPT_PB,
	OPT_MODE,
	OPT_NICE,
	OPT_MF,
	OPT_DEPTH,
};


static void lzma_attribute((noreturn))
error_lzma_preset(const char *valuestr)
{
	message_fatal(_("Unsupported LZMA1/LZMA2 preset: %s"), valuestr);
}


static void
set_lzma(void *options, uint32_t key, uint64_t value, const char *valuestr)
{
	lzma_options_lzma *opt = options;

	switch (key) {
	case OPT_PRESET: {
		if (valuestr[0] < '0' || valuestr[0] > '9')
			error_lzma_preset(valuestr);

		uint32_t preset = valuestr[0] - '0';

		// Currently only "e" is supported as a modifier,
		// so keep this simple for now.
		if (valuestr[1] != '\0') {
			if (valuestr[1] == 'e')
				preset |= LZMA_PRESET_EXTREME;
			else
				error_lzma_preset(valuestr);

			if (valuestr[2] != '\0')
				error_lzma_preset(valuestr);
		}

		if (lzma_lzma_preset(options, preset))
			error_lzma_preset(valuestr);

		break;
	}

	case OPT_DICT:
		opt->dict_size = value;
		break;

	case OPT_LC:
		opt->lc = value;
		break;

	case OPT_LP:
		opt->lp = value;
		break;

	case OPT_PB:
		opt->pb = value;
		break;

	case OPT_MODE:
		opt->mode = value;
		break;

	case OPT_NICE:
		opt->nice_len = value;
		break;

	case OPT_MF:
		opt->mf = value;
		break;

	case OPT_DEPTH:
		opt->depth = value;
		break;
	}
}


extern lzma_options_lzma *
options_lzma(const char *str)
{
	static const name_id_map modes[] = {
		{ "fast",   LZMA_MODE_FAST },
		{ "normal", LZMA_MODE_NORMAL },
		{ NULL,     0 }
	};

	static const name_id_map mfs[] = {
		{ "hc3", LZMA_MF_HC3 },
		{ "hc4", LZMA_MF_HC4 },
		{ "bt2", LZMA_MF_BT2 },
		{ "bt3", LZMA_MF_BT3 },
		{ "bt4", LZMA_MF_BT4 },
		{ NULL,  0 }
	};

	static const option_map opts[] = {
		{ "preset", NULL,   UINT64_MAX, 0 },
		{ "dict",   NULL,   LZMA_DICT_SIZE_MIN,
				(UINT32_C(1) << 30) + (UINT32_C(1) << 29) },
		{ "lc",     NULL,   LZMA_LCLP_MIN, LZMA_LCLP_MAX },
		{ "lp",     NULL,   LZMA_LCLP_MIN, LZMA_LCLP_MAX },
		{ "pb",     NULL,   LZMA_PB_MIN, LZMA_PB_MAX },
		{ "mode",   modes,  0, 0 },
		{ "nice",   NULL,   2, 273 },
		{ "mf",     mfs,    0, 0 },
		{ "depth",  NULL,   0, UINT32_MAX },
		{ NULL,     NULL,   0, 0 }
	};

	lzma_options_lzma *options = xmalloc(sizeof(lzma_options_lzma));
	*options = (lzma_options_lzma){
		.dict_size = LZMA_DICT_SIZE_DEFAULT,
		.preset_dict =  NULL,
		.preset_dict_size = 0,
		.lc = LZMA_LC_DEFAULT,
		.lp = LZMA_LP_DEFAULT,
		.pb = LZMA_PB_DEFAULT,
		.mode = LZMA_MODE_NORMAL,
		.nice_len = 64,
		.mf = LZMA_MF_BT4,
		.depth = 0,
	};

	parse_options(str, opts, &set_lzma, options);

	if (options->lc + options->lp > LZMA_LCLP_MAX)
		message_fatal(_("The sum of lc and lp must be at "
				"maximum of 4"));

	const uint32_t nice_len_min = options->mf & 0x0F;
	if (options->nice_len < nice_len_min)
		message_fatal(_("The selected match finder requires at "
				"least nice=%" PRIu32), nice_len_min);

	return options;
}
