/*
 * Copyright (C) 2013 Michael Brown <mbrown@fensystems.co.uk>.
 *
 * This program 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 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
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 *
 * You can also choose to distribute this program under the terms of
 * the Unmodified Binary Distribution Licence (as given in the file
 * COPYING.UBDL), provided that you have satisfied its requirements.
 */

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
FILE_SECBOOT ( PERMITTED );

/** @file
 *
 * Request parameters
 *
 */

#include <stdlib.h>
#include <string.h>
#include <ipxe/params.h>

/** List of all parameter lists */
static LIST_HEAD ( parameters );

/**
 * Free request parameter list
 *
 * @v refcnt		Reference count
 */
static void free_parameters ( struct refcnt *refcnt ) {
	struct parameters *params =
		container_of ( refcnt, struct parameters, refcnt );
	struct parameter *param;
	struct parameter *tmp;

	DBGC ( params, "PARAMS \"%s\" destroyed\n", params->name );

	/* Free all parameters */
	list_for_each_entry_safe ( param, tmp, &params->entries, list ) {
		list_del ( &param->list );
		free ( param );
	}

	/* Free parameter list */
	free ( params );
}

/**
 * Find request parameter list by name
 *
 * @v name		Parameter list name (may be NULL)
 * @ret params		Parameter list, or NULL if not found
 */
struct parameters * find_parameters ( const char *name ) {
	struct parameters *params;

	list_for_each_entry ( params, &parameters, list ) {
		if ( ( params->name == name ) ||
		     ( params->name && name &&
		       ( strcmp ( params->name, name ) == 0 ) ) ) {
			return params;
		}
	}
	return NULL;
}

/**
 * Create request parameter list
 *
 * @v name		Parameter list name (may be NULL)
 * @v method		Method name (may be NULL)
 * @ret params		Parameter list, or NULL on failure
 */
struct parameters * create_parameters ( const char *name,
					const char *method ) {
	struct parameters *params;
	size_t name_len;
	size_t method_len;
	char *name_copy;
	char *method_copy;

	/* Destroy any existing parameter list of this name */
	params = find_parameters ( name );
	if ( params ) {
		claim_parameters ( params );
		params_put ( params );
	}

	/* Allocate parameter list */
	name_len = ( name ? ( strlen ( name ) + 1 /* NUL */ ) : 0 );
	method_len = ( method ? ( strlen ( method ) + 1 /* NUL */ ) : 0 );
	params = zalloc ( sizeof ( *params ) + name_len + method_len );
	if ( ! params )
		return NULL;
	ref_init ( &params->refcnt, free_parameters );
	name_copy = ( ( ( void * ) params ) + sizeof ( *params ) );
	method_copy = ( ( ( void * ) name_copy ) + name_len );

	/* Populate parameter list */
	if ( name ) {
		strcpy ( name_copy, name );
		params->name = name_copy;
	}
	if ( method ) {
		strcpy ( method_copy, method );
		params->method = method_copy;
	}
	INIT_LIST_HEAD ( &params->entries );

	/* Add to list of parameter lists */
	list_add_tail ( &params->list, &parameters );

	DBGC ( params, "PARAMS \"%s\" created\n", params->name );
	if ( params->method ) {
		DBGC ( params, "PARAMS \"%s\" method is \"%s\"\n",
		       params->name, params->method );
	}
	return params;
}

/**
 * Add request parameter
 *
 * @v params		Parameter list
 * @v key		Parameter key
 * @v value		Parameter value
 * @v flags		Parameter flags
 * @ret param		Parameter, or NULL on failure
 */
struct parameter * add_parameter ( struct parameters *params,
				   const char *key, const char *value,
				   unsigned int flags ) {
	struct parameter *param;
	size_t key_len;
	size_t value_len;
	char *key_copy;
	char *value_copy;

	/* Allocate parameter */
	key_len = ( strlen ( key ) + 1 /* NUL */ );
	value_len = ( strlen ( value ) + 1 /* NUL */ );
	param = zalloc ( sizeof ( *param ) + key_len + value_len );
	if ( ! param )
		return NULL;
	key_copy = ( ( void * ) ( param + 1 ) );
	value_copy = ( key_copy + key_len );

	/* Populate parameter */
	strcpy ( key_copy, key );
	param->key = key_copy;
	strcpy ( value_copy, value );
	param->value = value_copy;
	param->flags = flags;

	/* Add to list of parameters */
	list_add_tail ( &param->list, &params->entries );

	DBGC ( params, "PARAMS \"%s\" added \"%s\"=\"%s\"%s%s\n",
	       params->name, param->key, param->value,
	       ( ( param->flags & PARAMETER_FORM ) ? " (form)" : "" ),
	       ( ( param->flags & PARAMETER_HEADER ) ? " (header)" : "" ) );
	return param;
}
