/*
 * Copyright (C) 2006 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., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <stddef.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <assert.h>
#include <libgen.h>
#include <gpxe/list.h>
#include <gpxe/umalloc.h>
#include <gpxe/uri.h>
#include <gpxe/image.h>

/** @file
 *
 * Executable/loadable images
 *
 */

/** List of registered images */
struct list_head images = LIST_HEAD_INIT ( images );

/** List of image types */
static struct image_type image_types[0]
	__table_start ( struct image_type, image_types );
static struct image_type image_types_end[0]
	__table_end ( struct image_type, image_types );

/**
 * Free executable/loadable image
 *
 * @v refcnt		Reference counter
 */
static void free_image ( struct refcnt *refcnt ) {
	struct image *image = container_of ( refcnt, struct image, refcnt );

	uri_put ( image->uri );
	ufree ( image->data );
	free ( image );
	DBGC ( image, "IMAGE %p freed\n", image );
}

/**
 * Allocate executable/loadable image
 *
 * @ret image		Executable/loadable image
 */
struct image * alloc_image ( void ) {
	struct image *image;

	image = zalloc ( sizeof ( *image ) );
	if ( image ) {
		image->refcnt.free = free_image;
	}
	return image;
}

/**
 * Set image URI
 *
 * @v image		Image
 * @v URI		New image URI
 * @ret rc		Return status code
 *
 * If no name is set, the name will be updated to the base name of the
 * URI path (if any).
 */
int image_set_uri ( struct image *image, struct uri *uri ) {
	const char *path = uri->path;

	/* Replace URI reference */
	uri_put ( image->uri );
	image->uri = uri_get ( uri );

	/* Set name if none already specified */
	if ( path && ( ! image->name[0] ) )
		image_set_name ( image, basename ( ( char * ) path ) );

	return 0;
}

/**
 * Set image command line
 *
 * @v image		Image
 * @v cmdline		New image command line
 * @ret rc		Return status code
 */
int image_set_cmdline ( struct image *image, const char *cmdline ) {
	free ( image->cmdline );
	image->cmdline = strdup ( cmdline );
	if ( ! image->cmdline )
		return -ENOMEM;
	return 0;
}

/**
 * Register executable/loadable image
 *
 * @v image		Executable/loadable image
 * @ret rc		Return status code
 */
int register_image ( struct image *image ) {
	static unsigned int imgindex = 0;

	/* Create image name if it doesn't already have one */
	if ( ! image->name[0] ) {
		snprintf ( image->name, sizeof ( image->name ), "img%d",
			   imgindex++ );
	}

	/* Add to image list */
	image_get ( image );
	list_add_tail ( &image->list, &images );
	DBGC ( image, "IMAGE %p at [%lx,%lx) registered as %s\n",
	       image, user_to_phys ( image->data, 0 ),
	       user_to_phys ( image->data, image->len ), image->name );

	return 0;
}

/**
 * Unregister executable/loadable image
 *
 * @v image		Executable/loadable image
 */
void unregister_image ( struct image *image ) {
	list_del ( &image->list );
	image_put ( image );
	DBGC ( image, "IMAGE %p unregistered\n", image );
}

/**
 * Find image by name
 *
 * @v name		Image name
 * @ret image		Executable/loadable image, or NULL
 */
struct image * find_image ( const char *name ) {
	struct image *image;

	list_for_each_entry ( image, &images, list ) {
		if ( strcmp ( image->name, name ) == 0 )
			return image;
	}

	return NULL;
}

/**
 * Load executable/loadable image into memory
 *
 * @v image		Executable/loadable image
 * @v type		Executable/loadable image type
 * @ret rc		Return status code
 */
static int image_load_type ( struct image *image, struct image_type *type ) {
	int rc;

	/* Check image is actually loadable */
	if ( ! type->load )
		return -ENOEXEC;

	/* Try the image loader */
	if ( ( rc = type->load ( image ) ) != 0 ) {
		DBGC ( image, "IMAGE %p could not load as %s: %s\n",
		       image, type->name, strerror ( rc ) );
		return rc;
	}

	/* Flag as loaded */
	image->flags |= IMAGE_LOADED;
	return 0;
}

/**
 * Load executable/loadable image into memory
 *
 * @v image		Executable/loadable image
 * @ret rc		Return status code
 */
int image_load ( struct image *image ) {

	assert ( image->type != NULL );

	return image_load_type ( image, image->type );
}

/**
 * Autodetect image type and load executable/loadable image into memory
 *
 * @v image		Executable/loadable image
 * @ret rc		Return status code
 */
int image_autoload ( struct image *image ) {
	struct image_type *type;
	int rc;

	/* If image already has a type, use it */
	if ( image->type )
		return image_load ( image );

	/* Otherwise probe for a suitable type */
	for ( type = image_types ; type < image_types_end ; type++ ) {
		DBGC ( image, "IMAGE %p trying type %s\n", image, type->name );
		rc = image_load_type ( image, type );
		if ( image->type == NULL )
			continue;
		return rc;
	}

	DBGC ( image, "IMAGE %p format not recognised\n", image );
	return -ENOEXEC;
}

/**
 * Execute loaded image
 *
 * @v image		Loaded image
 * @ret rc		Return status code
 */
int image_exec ( struct image *image ) {
	struct uri *old_cwuri;
	int rc;

	/* Image must be loaded first */
	if ( ! ( image->flags & IMAGE_LOADED ) ) {
		DBGC ( image, "IMAGE %p could not execute: not loaded\n",
		       image );
		return -ENOTTY;
	}

	assert ( image->type != NULL );

	/* Check that image is actually executable */
	if ( ! image->type->exec )
		return -ENOEXEC;

	/* Switch current working directory to be that of the image itself */
	old_cwuri = uri_get ( cwuri );
	churi ( image->uri );

	/* Try executing the image */
	if ( ( rc = image->type->exec ( image ) ) != 0 ) {
		DBGC ( image, "IMAGE %p could not execute: %s\n",
		       image, strerror ( rc ) );
		goto done;
	}

 done:
	/* Reset current working directory */
	churi ( old_cwuri );
	uri_put ( old_cwuri );

	return rc;
}

/**
 * Register and autoload an image
 *
 * @v image		Image
 * @ret rc		Return status code
 */
int register_and_autoload_image ( struct image *image ) {
	int rc;

	if ( ( rc = register_image ( image ) ) != 0 )
		return rc;

	if ( ( rc = image_autoload ( image ) ) != 0 )
		return rc;

	return 0;
}

/**
 * Register and autoexec an image
 *
 * @v image		Image
 * @ret rc		Return status code
 */
int register_and_autoexec_image ( struct image *image ) {
	int rc;

	if ( ( rc = register_and_autoload_image ( image ) ) != 0 )
		return rc;

	if ( ( rc = image_exec ( image ) ) != 0 )
		return rc;

	return 0;
}
