/*
 * 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
 *
 * Convert a PFI file (partial flash image) into a plain binary file.
 * This tool can be used to prepare the data to be burned into flash
 * chips in a manufacturing step where the flashes are written before
 * being soldered onto the hardware. For NAND images another step is
 * required to add the right OOB data to the binary image.
 *
 * 1.3 Removed argp because we want to use uClibc.
 * 1.4 Minor cleanups
 */

#include <stdlib.h>
#include <stdint.h>
#include <getopt.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <errno.h>

#include <ubigen.h>
#include <mtd/ubi-media.h>
#include <mtd_swab.h>

#include "config.h"
#include "list.h"
#include "error.h"
#include "reader.h"
#include "peb.h"
#include "crc32.h"

#define PROGRAM_VERSION "1.4"

#define MAX_FNAME 255
#define DEFAULT_ERASE_COUNT  0 /* Hmmm.... Perhaps */
#define ERR_BUF_SIZE 1024

#define MIN(a,b) ((a) < (b) ? (a) : (b))

static uint32_t crc32_table[256];
static char err_buf[ERR_BUF_SIZE];

/*
 * Data used to buffer raw blocks which have to be
 * located at a specific point inside the generated RAW file
 */

typedef enum action_t {
	ACT_NOTHING   = 0x00000000,
	ACT_RAW	   = 0x00000001,
} action_t;

static const char copyright [] __attribute__((unused)) =
	"(c) Copyright IBM Corp 2006\n";

static char doc[] = "\nVersion: " PROGRAM_VERSION "\n"
	"pfi2bin - a tool to convert PFI files into binary images.\n";

static const char *optionsstr =
" Common settings:\n"
"  -c, --copyright\n"
"  -v, --verbose              Print more information.\n"
"\n"
" Input:\n"
"  -j, --platform=pdd-file    PDD information which contains the card settings.\n"
"\n"
" Output:\n"
"  -o, --output=filename      Outputfile, default: stdout.\n"
"\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: pfi2bin [-cv?V] [-j pdd-file] [-o filename] [--copyright]\n"
"            [--verbose] [--platform=pdd-file] [--output=filename] [--help]\n"
"            [--usage] [--version] pfifile\n";

struct option long_options[] = {
	{ .name = "copyright", .has_arg = 0, .flag = NULL, .val = 'c' },
	{ .name = "verbose", .has_arg = 0, .flag = NULL, .val = 'v' },
	{ .name = "platform", .has_arg = 1, .flag = NULL, .val = 'j' },
	{ .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 io {
	FILE* fp_pdd;	/* a FilePointer to the PDD data */
	FILE* fp_pfi;	/* a FilePointer to the PFI input stream */
	FILE* fp_out;	/* a FilePointer to the output stream */
} *io_t;

typedef struct myargs {
	/* common settings */
	action_t action;
	int verbose;
	const char *f_in_pfi;
	const char *f_in_pdd;
	const char *f_out;

	/* special stuff needed to get additional arguments */
	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, "cvj:o:?V", long_options, NULL);
		if (key == -1)
			break;

		switch (key) {
			/* common settings */
			case 'v': /* --verbose=<level> */
				args->verbose = 1;
				break;

			case 'c': /* --copyright */
				fprintf(stderr, "%s\n", copyright);
				exit(0);
				break;

			case 'j': /* --platform */
				args->f_in_pdd = optarg;
				break;

			case 'o': /* --output */
				args->f_out = optarg;
				break;

			case '?': /* help */
				printf("pfi2bin [OPTION...] pfifile\n");
				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->f_in_pfi = argv[optind++];

	return 0;
}


static size_t
byte_to_blk(size_t byte, size_t blk_size)
{
	return	(byte % blk_size) == 0
		? byte / blk_size
		: byte / blk_size + 1;
}




/**
 * @precondition  IO: File stream points to first byte of RAW data.
 * @postcondition IO: File stream points to first byte of next
 *		      or EOF.
 */
static int
memorize_raw_eb(pfi_raw_t pfi_raw, pdd_data_t pdd, list_t *raw_pebs,
		io_t io)
{
	int rc = 0;
	uint32_t i;

	size_t read, to_read, eb_num;
	size_t bytes_left;
	list_t pebs = *raw_pebs;
	peb_t	peb  = NULL;

	long old_file_pos = ftell(io->fp_pfi);
	for (i = 0; i < pfi_raw->starts_size; i++) {
		bytes_left = pfi_raw->data_size;
		rc = fseek(io->fp_pfi, old_file_pos, SEEK_SET);
		if (rc != 0)
			goto err;

		eb_num = byte_to_blk(pfi_raw->starts[i], pdd->eb_size);
		while (bytes_left) {
			to_read = MIN(bytes_left, pdd->eb_size);
			rc = peb_new(eb_num++, pdd->eb_size, &peb);
			if (rc != 0)
				goto err;
			read = fread(peb->data, 1, to_read, io->fp_pfi);
			if (read != to_read) {
				rc = -EIO;
				goto err;
			}
			pebs = append_elem(peb, pebs);
			bytes_left -= read;
		}

	}
	*raw_pebs = pebs;
	return 0;
err:
	pebs = remove_all((free_func_t)&peb_free, pebs);
	return rc;
}

static int
convert_ubi_volume(pfi_ubi_t ubi, pdd_data_t pdd, list_t raw_pebs,
		struct ubi_vtbl_record *vol_tab,
		size_t *ebs_written, io_t io)
{
	int rc = 0;
	uint32_t i, j;
	peb_t raw_peb;
	peb_t cmp_peb;
	ubi_info_t u;
	size_t leb_total = 0;
	uint8_t vol_type;

	switch (ubi->type) {
	case pfi_ubi_static:
		vol_type = UBI_VID_STATIC; break;
	case pfi_ubi_dynamic:
		vol_type = UBI_VID_DYNAMIC; break;
	default:
		vol_type = UBI_VID_DYNAMIC;
	}

	rc = peb_new(0, 0, &cmp_peb);
	if (rc != 0)
		goto err;

	long old_file_pos = ftell(io->fp_pfi);
	for (i = 0; i < ubi->ids_size; i++) {
		rc = fseek(io->fp_pfi, old_file_pos, SEEK_SET);
		if (rc != 0)
			goto err;
		rc = ubigen_create(&u, ubi->ids[i], vol_type,
				   pdd->eb_size, DEFAULT_ERASE_COUNT,
				   ubi->alignment, UBI_VERSION,
				   pdd->vid_hdr_offset, 0, ubi->data_size,
				   io->fp_pfi, io->fp_out);
		if (rc != 0)
			goto err;

		rc = ubigen_get_leb_total(u, &leb_total);
		if (rc != 0)
			goto err;

		j = 0;
		while(j < leb_total) {
			cmp_peb->num = *ebs_written;
			raw_peb = is_in((cmp_func_t)peb_cmp, cmp_peb,
					raw_pebs);
			if (raw_peb) {
				rc = peb_write(io->fp_out, raw_peb);
			}
			else {
				rc = ubigen_write_leb(u, NO_ERROR);
				j++;
			}
			if (rc != 0)
				goto err;
			(*ebs_written)++;
		}
		/* memorize volume table entry */
		rc = ubigen_set_lvol_rec(u, ubi->size,
				ubi->names[i],
				(void*) &vol_tab[ubi->ids[i]]);
		if (rc != 0)
			goto err;
		ubigen_destroy(&u);
	}

	peb_free(&cmp_peb);
	return 0;

err:
	peb_free(&cmp_peb);
	ubigen_destroy(&u);
	return rc;
}


static FILE*
my_fmemopen (void *buf, size_t size, const char *opentype)
{
    FILE* f;
    size_t ret;

    assert(strcmp(opentype, "r") == 0);

    f = tmpfile();
    ret = fwrite(buf, 1, size, f);
    rewind(f);

    return f;
}

/**
 * @brief		Builds a UBI volume table from a volume entry list.
 * @return 0		On success.
 *	   else		Error.
 */
static int
write_ubi_volume_table(pdd_data_t pdd, list_t raw_pebs,
		struct ubi_vtbl_record *vol_tab, size_t vol_tab_size,
		size_t *ebs_written, io_t io)
{
	int rc = 0;
	ubi_info_t u;
	peb_t raw_peb;
	peb_t cmp_peb;
	size_t leb_size, leb_total, j = 0;
	uint8_t *ptr = NULL;
	FILE* fp_leb = NULL;
	int vt_slots;
	size_t vol_tab_size_limit;

	rc = peb_new(0, 0, &cmp_peb);
	if (rc != 0)
		goto err;

	/* @FIXME: Artem creates one volume with 2 LEBs.
	 * IMO 2 volumes would be more convenient. In order
	 * to get 2 reserved LEBs from ubigen, I have to
	 * introduce this stupid mechanism. Until no final
	 * decision of the VTAB structure is made... Good enough.
	 */
	rc = ubigen_create(&u, UBI_LAYOUT_VOLUME_ID, UBI_VID_DYNAMIC,
			   pdd->eb_size, DEFAULT_ERASE_COUNT,
			   1, UBI_VERSION,
			   pdd->vid_hdr_offset, UBI_COMPAT_REJECT,
			   vol_tab_size, stdin, io->fp_out);
			   /* @FIXME stdin for fp_in is a hack */
	if (rc != 0)
		goto err;
	rc = ubigen_get_leb_size(u, &leb_size);
	if (rc != 0)
		goto err;
	ubigen_destroy(&u);

	/*
	 * The number of supported volumes is restricted by the eraseblock size
	 * and by the UBI_MAX_VOLUMES constant.
	 */
	vt_slots = leb_size / UBI_VTBL_RECORD_SIZE;
	if (vt_slots > UBI_MAX_VOLUMES)
		vt_slots = UBI_MAX_VOLUMES;
	vol_tab_size_limit = vt_slots * UBI_VTBL_RECORD_SIZE;

	ptr = (uint8_t*) malloc(leb_size * sizeof(uint8_t));
	if (ptr == NULL)
		goto err;

	memset(ptr, 0xff, leb_size);
	memcpy(ptr, vol_tab, vol_tab_size_limit);
	fp_leb = my_fmemopen(ptr, leb_size, "r");

	rc = ubigen_create(&u, UBI_LAYOUT_VOLUME_ID, UBI_VID_DYNAMIC,
			   pdd->eb_size, DEFAULT_ERASE_COUNT,
			   1, UBI_VERSION, pdd->vid_hdr_offset,
			   UBI_COMPAT_REJECT, leb_size * UBI_LAYOUT_VOLUME_EBS,
			   fp_leb, io->fp_out);
	if (rc != 0)
		goto err;
	rc = ubigen_get_leb_total(u, &leb_total);
	if (rc != 0)
		goto err;

	long old_file_pos = ftell(fp_leb);
	while(j < leb_total) {
		rc = fseek(fp_leb, old_file_pos, SEEK_SET);
		if (rc != 0)
			goto err;

		cmp_peb->num = *ebs_written;
		raw_peb = is_in((cmp_func_t)peb_cmp, cmp_peb,
				raw_pebs);
		if (raw_peb) {
			rc = peb_write(io->fp_out, raw_peb);
		}
		else {
			rc = ubigen_write_leb(u, NO_ERROR);
			j++;
		}

		if (rc != 0)
			goto err;
		(*ebs_written)++;
	}

err:
	free(ptr);
	peb_free(&cmp_peb);
	ubigen_destroy(&u);
	fclose(fp_leb);
	return rc;
}

static int
write_remaining_raw_ebs(pdd_data_t pdd, list_t raw_blocks, size_t *ebs_written,
			FILE* fp_out)
{
	int rc = 0;
	uint32_t j, delta;
	list_t ptr;
	peb_t empty_eb, peb;

	/* create an empty 0xff EB (for padding) */
	rc = peb_new(0, pdd->eb_size, &empty_eb);

	foreach(peb, ptr, raw_blocks) {
		if (peb->num < *ebs_written) {
			continue; /* omit blocks which
				     are already passed */
		}

		if (peb->num < *ebs_written) {
			err_msg("eb_num: %d\n", peb->num);
			err_msg("Bug: This should never happen. %d %s",
				__LINE__, __FILE__);
			goto err;
		}

		delta = peb->num - *ebs_written;
		if (((delta + *ebs_written) * pdd->eb_size) > pdd->flash_size) {
			err_msg("RAW block outside of flash_size.");
			goto err;
		}
		for (j = 0; j < delta; j++) {
			rc = peb_write(fp_out, empty_eb);
			if (rc != 0)
				goto err;
			(*ebs_written)++;
		}
		rc = peb_write(fp_out, peb);
		if (rc != 0)
			goto err;
		(*ebs_written)++;
	}

err:
	peb_free(&empty_eb);
	return rc;
}

static int
init_vol_tab(struct ubi_vtbl_record **vol_tab, size_t *vol_tab_size)
{
	uint32_t crc;
	size_t i;
	struct ubi_vtbl_record* res = NULL;

	*vol_tab_size = UBI_MAX_VOLUMES * UBI_VTBL_RECORD_SIZE;

	res = (struct ubi_vtbl_record*) calloc(1, *vol_tab_size);
	if (vol_tab == NULL) {
		return -ENOMEM;
	}

	for (i = 0; i < UBI_MAX_VOLUMES; i++) {
		crc = clc_crc32(crc32_table, UBI_CRC32_INIT,
			&(res[i]), UBI_VTBL_RECORD_SIZE_CRC);
		res[i].crc = cpu_to_be32(crc);
	}

	*vol_tab = res;
	return 0;
}

static int
create_raw(io_t io)
{
	int rc = 0;
	size_t ebs_written = 0; /* eraseblocks written already... */
	size_t vol_tab_size;
	list_t ptr;

	list_t pfi_raws = mk_empty(); /* list of raw sections from a pfi */
	list_t pfi_ubis = mk_empty(); /* list of ubi sections from a pfi */
	list_t raw_pebs	 = mk_empty(); /* list of raw eraseblocks */

	struct ubi_vtbl_record *vol_tab = NULL;
	pdd_data_t pdd = NULL;

	rc = init_vol_tab (&vol_tab, &vol_tab_size);
	if (rc != 0) {
		err_msg("Cannot initialize volume table.");
		goto err;
	}

	rc = read_pdd_data(io->fp_pdd, &pdd,
			err_buf, ERR_BUF_SIZE);
	if (rc != 0) {
		err_msg("Cannot read necessary pdd_data: %s rc: %d",
				err_buf, rc);
		goto err;
	}

	rc = read_pfi_headers(&pfi_raws, &pfi_ubis, io->fp_pfi,
			err_buf, ERR_BUF_SIZE);
	if (rc != 0) {
		err_msg("Cannot read pfi header: %s rc: %d",
				err_buf, rc);
		goto err;
	}

	pfi_raw_t pfi_raw;
	foreach(pfi_raw, ptr, pfi_raws) {
		rc = memorize_raw_eb(pfi_raw, pdd, &raw_pebs,
			io);
		if (rc != 0) {
			err_msg("Cannot create raw_block in mem. rc: %d\n",
				rc);
			goto err;
		}
	}

	pfi_ubi_t pfi_ubi;
	foreach(pfi_ubi, ptr, pfi_ubis) {
		rc = convert_ubi_volume(pfi_ubi, pdd, raw_pebs,
					vol_tab, &ebs_written, io);
		if (rc != 0) {
			err_msg("Cannot convert UBI volume. rc: %d\n", rc);
			goto err;
		}
	}

	rc = write_ubi_volume_table(pdd, raw_pebs, vol_tab, vol_tab_size,
			&ebs_written, io);
	if (rc != 0) {
		err_msg("Cannot write UBI volume table. rc: %d\n", rc);
		goto err;
	}

	rc  = write_remaining_raw_ebs(pdd, raw_pebs, &ebs_written, io->fp_out);
	if (rc != 0)
		goto err;

	if (io->fp_out != stdout)
		info_msg("Physical eraseblocks written: %8d\n", ebs_written);
err:
	free(vol_tab);
	pfi_raws = remove_all((free_func_t)&free_pfi_raw, pfi_raws);
	pfi_ubis = remove_all((free_func_t)&free_pfi_ubi, pfi_ubis);
	raw_pebs = remove_all((free_func_t)&peb_free, raw_pebs);
	free_pdd_data(&pdd);
	return rc;
}


/* ------------------------------------------------------------------------- */
static void
open_io_handle(myargs *args, io_t io)
{
	/* set PDD input */
	io->fp_pdd = fopen(args->f_in_pdd, "r");
	if (io->fp_pdd == NULL) {
		err_sys("Cannot open: %s", args->f_in_pdd);
	}

	/* set PFI input */
	io->fp_pfi = fopen(args->f_in_pfi, "r");
	if (io->fp_pfi == NULL) {
		err_sys("Cannot open PFI input file: %s", args->f_in_pfi);
	}

	/* set output prefix */
	if (strcmp(args->f_out,"") == 0)
		io->fp_out = stdout;
	else {
		io->fp_out = fopen(args->f_out, "wb");
		if (io->fp_out == NULL) {
			err_sys("Cannot open output file: %s", args->f_out);
		}
	}
}

static void
close_io_handle(io_t io)
{
	if (fclose(io->fp_pdd) != 0) {
		err_sys("Cannot close PDD file.");
	}
	if (fclose(io->fp_pfi) != 0) {
		err_sys("Cannot close PFI file.");
	}
	if (io->fp_out != stdout) {
		if (fclose(io->fp_out) != 0) {
			err_sys("Cannot close output file.");
		}
	}

	io->fp_pdd = NULL;
	io->fp_pfi = NULL;
	io->fp_out = NULL;
}

int
main(int argc, char *argv[])
{
	int rc = 0;

	ubigen_init();
	init_crc32_table(crc32_table);

	struct io io = {NULL, NULL, NULL};
	myargs args = {
		.action = ACT_RAW,
		.verbose = 0,

		.f_in_pfi = "",
		.f_in_pdd = "",
		.f_out = "",

		/* arguments */
		.arg1 = NULL,
		.options = NULL,
	};

	/* parse arguments */
	parse_opt(argc, argv, &args);

	if (strcmp(args.f_in_pfi, "") == 0) {
		err_quit("No PFI input file specified!");
	}

	if (strcmp(args.f_in_pdd, "") == 0) {
		err_quit("No PDD input file specified!");
	}

	open_io_handle(&args, &io);

	info_msg("[ Creating RAW...");
	rc = create_raw(&io);
	if (rc != 0) {
		err_msg("Creating RAW failed.");
		goto err;
	}

err:
	close_io_handle(&io);
	if (rc != 0) {
		remove(args.f_out);
	}

	return rc;
}
