///////////////////////////////////////////////////////////////////////////////
//
/// \file       options.c
/// \brief      Parser for filter-specific options
//
//  Copyright (C) 2007 Lasse Collin
//
//  This program is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2.1 of the License, or (at your option) any later version.
//
//  This program 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
//  Lesser General Public License for more details.
//
///////////////////////////////////////////////////////////////////////////////

#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 either a number with minimum and maximum value limit, or
/// a string-id map mapping a list of possible string values to integers.
///
/// 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),
		void *filter_options)
{
	if (str == NULL || str[0] == '\0')
		return;

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

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

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

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

		// Look for the option name from the option map.
		bool found = false;
		for (size_t i = 0; opts[i].name != NULL; ++i) {
			if (strcmp(name, opts[i].name) != 0)
				continue;

			if (opts[i].map == NULL) {
				// value is an integer.
				const uint64_t v = str_to_uint64(name, value,
						opts[i].min, opts[i].max);
				set(filter_options, i, v);
			} else {
				// 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) {
					errmsg(V_ERROR, _("%s: Invalid option "
							"value"), value);
					my_exit(ERROR);
				}

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

			found = true;
			break;
		}

		if (!found) {
			errmsg(V_ERROR, _("%s: Invalid option name"), name);
			my_exit(ERROR);
		}

		if (split == NULL)
			break;

		name = split + 1;
	}

	free(s);
	return;
}


//////////////
// Subblock //
//////////////

enum {
	OPT_SIZE,
	OPT_RLE,
	OPT_ALIGN,
};


static void
set_subblock(void *options, uint32_t key, uint64_t value)
{
	lzma_options_subblock *opt = options;

	switch (key) {
	case OPT_SIZE:
		opt->subblock_data_size = value;
		break;

	case OPT_RLE:
		opt->rle = value;
		break;

	case OPT_ALIGN:
		opt->alignment = value;
		break;
	}
}


extern lzma_options_subblock *
parse_options_subblock(const char *str)
{
	static const option_map opts[] = {
		{ "size", NULL,   LZMA_SUBBLOCK_DATA_SIZE_MIN,
		                  LZMA_SUBBLOCK_DATA_SIZE_MAX },
		{ "rle",  NULL,   LZMA_SUBBLOCK_RLE_OFF,
		                  LZMA_SUBBLOCK_RLE_MAX },
		{ "align",NULL,   LZMA_SUBBLOCK_ALIGNMENT_MIN,
		                  LZMA_SUBBLOCK_ALIGNMENT_MAX },
		{ NULL,   NULL,   0, 0 }
	};

	lzma_options_subblock *options
			= xmalloc(sizeof(lzma_options_subblock));
	*options = (lzma_options_subblock){
		.allow_subfilters = false,
		.alignment = LZMA_SUBBLOCK_ALIGNMENT_DEFAULT,
		.subblock_data_size = LZMA_SUBBLOCK_DATA_SIZE_DEFAULT,
		.rle = LZMA_SUBBLOCK_RLE_OFF,
	};

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

	return options;
}


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

enum {
	OPT_DISTANCE,
};


static void
set_delta(void *options, uint32_t key, uint64_t value)
{
	lzma_options_delta *opt = options;
	switch (key) {
	case OPT_DISTANCE:
		opt->distance = value;
		break;
	}
}


extern lzma_options_delta *
parse_options_delta(const char *str)
{
	static const option_map opts[] = {
		{ "distance", NULL,  LZMA_DELTA_DISTANCE_MIN,
		                     LZMA_DELTA_DISTANCE_MAX },
		{ NULL,       NULL,  0, 0 }
	};

	lzma_options_delta *options = xmalloc(sizeof(lzma_options_subblock));
	*options = (lzma_options_delta){
		// It's hard to give a useful default for this.
		.distance = LZMA_DELTA_DISTANCE_MIN,
	};

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

	return options;
}


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

enum {
	OPT_DICT,
	OPT_LC,
	OPT_LP,
	OPT_PB,
	OPT_MODE,
	OPT_FB,
	OPT_MF,
	OPT_MC
};


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

	switch (key) {
	case OPT_DICT:
		opt->dictionary_size = value;
		break;

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

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

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

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

	case OPT_FB:
		opt->fast_bytes = value;
		break;

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

	case OPT_MC:
		opt->match_finder_cycles = value;
		break;
	}
}


extern lzma_options_lzma *
parse_options_lzma(const char *str)
{
	static const name_id_map modes[] = {
		{ "fast", LZMA_MODE_FAST },
		{ "best", LZMA_MODE_BEST },
		{ 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[] = {
		{ "dict", NULL,   LZMA_DICTIONARY_SIZE_MIN,
				LZMA_DICTIONARY_SIZE_MAX },
		{ "lc",   NULL,   LZMA_LITERAL_CONTEXT_BITS_MIN,
				  LZMA_LITERAL_CONTEXT_BITS_MAX },
		{ "lp",   NULL,   LZMA_LITERAL_POS_BITS_MIN,
				  LZMA_LITERAL_POS_BITS_MAX },
		{ "pb",   NULL,   LZMA_POS_BITS_MIN, LZMA_POS_BITS_MAX },
		{ "mode", modes,  0, 0 },
		{ "fb",   NULL,   LZMA_FAST_BYTES_MIN, LZMA_FAST_BYTES_MAX },
		{ "mf",   mfs,    0, 0 },
		{ "mc",   NULL,   0, UINT32_MAX },
		{ NULL,   NULL,   0, 0 }
	};

	lzma_options_lzma *options = xmalloc(sizeof(lzma_options_lzma));
	*options = (lzma_options_lzma){
		.dictionary_size = LZMA_DICTIONARY_SIZE_DEFAULT,
		.literal_context_bits = LZMA_LITERAL_CONTEXT_BITS_DEFAULT,
		.literal_pos_bits = LZMA_LITERAL_POS_BITS_DEFAULT,
		.pos_bits = LZMA_POS_BITS_DEFAULT,
		.mode = LZMA_MODE_BEST,
		.fast_bytes = LZMA_FAST_BYTES_DEFAULT,
		.match_finder = LZMA_MF_BT4,
		.match_finder_cycles = 0,
	};

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

	return options;
}
