/*
 * Copyright (c) International Business Machines Corp., 2006
 *
 * 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
 * (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 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.
 *
 * Author: Oliver Lohmann
 *
 * Create boot-parameter/pdd data from an ASCII-text input file.
 *
 * 1.2 Removed argp because we want to use uClibc.
 * 1.3 Minor cleanup
 */

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <getopt.h>
#include <unistd.h>
#include <errno.h>
#include <mtd/ubi-media.h>

#include "config.h"
#include "bootenv.h"
#include "error.h"

#define PROGRAM_VERSION "1.3"

static char doc[] = "\nVersion: " PROGRAM_VERSION "\n"
	"mkbootenv - processes bootenv text files and convertes "
	"them into a binary format.\n";

static const char copyright [] __attribute__((unused)) =
	"Copyright (c) International Business Machines Corp., 2006";

static const char *optionsstr =
"  -c, --copyright          Print copyright informatoin.\n"
"  -o, --output=<fname>     Write the output data to <output> instead of\n"
"                           stdout.\n"
"  -?, --help               Give this help list\n"
"      --usage              Give a short usage message\n"
"  -V, --version            Print program version\n";

static const char *usage =
"Usage: mkbootenv [-c?V] [-o <output>] [--copyright] [--output=<output>]\n"
"            [--help] [--usage] [--version] [bootenv-txt-file]\n";

struct option long_options[] = {
	{ .name = "copyright", .has_arg = 0, .flag = NULL, .val = 'c' },
	{ .name = "output", .has_arg = 1, .flag = NULL, .val = 'o' },
	{ .name = "help", .has_arg = 0, .flag = NULL, .val = '?' },
	{ .name = "usage", .has_arg = 0, .flag = NULL, .val = 0 },
	{ .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' },
	{ NULL, 0, NULL, 0}
};

typedef struct myargs {
	FILE* fp_in;
	FILE* fp_out;

	char *arg1;
	char **options;			/* [STRING...] */
} myargs;

static int
parse_opt(int argc, char **argv, myargs *args)
{
	while (1) {
		int key;

		key = getopt_long(argc, argv, "co:?V", long_options, NULL);
		if (key == -1)
			break;

		switch (key) {
			case 'c':
				fprintf(stderr, "%s\n", copyright);
				exit(0);
				break;
			case 'o':
				args->fp_out = fopen(optarg, "wb");
				if ((args->fp_out) == NULL) {
					fprintf(stderr, "Cannot open file %s "
						"for output\n", optarg);
					exit(1);
				}
				break;
			case '?': /* help */
				printf("%s", doc);
				printf("%s", optionsstr);
				printf("\nReport bugs to %s\n",
				       PACKAGE_BUGREPORT);
				exit(0);
				break;
			case 'V':
				printf("%s\n", PROGRAM_VERSION);
				exit(0);
				break;
			default:
				printf("%s", usage);
				exit(-1);
		}
	}

	if (optind < argc) {
		args->fp_in = fopen(argv[optind++], "rb");
		if ((args->fp_in) == NULL) {
			fprintf(stderr,	"Cannot open file %s for input\n",
				argv[optind]);
			exit(1);
		}
	}

	return 0;
}

int
main(int argc, char **argv) {
	int rc = 0;
	bootenv_t env;

	myargs args = {
		.fp_in = stdin,
		.fp_out = stdout,
		.arg1 = NULL,
		.options = NULL,
	};

	parse_opt(argc, argv, &args);

	rc = bootenv_create(&env);
	if (rc != 0) {
		err_msg("Cannot create bootenv handle.");
		goto err;
	}
	rc = bootenv_read_txt(args.fp_in, env);
	if (rc != 0) {
		err_msg("Cannot read bootenv from input file.");
		goto err;
	}
	rc = bootenv_write(args.fp_out, env);
	if (rc != 0) {
		err_msg("Cannot write bootenv to output file.");
		goto err;
	}

	if (args.fp_in != stdin) {
		fclose(args.fp_in);
	}
	if (args.fp_out != stdout) {
		fclose(args.fp_out);
	}

err:
	bootenv_destroy(&env);
	return rc;
}
