/*
 * Copyright (C) 2007, 2008 Nokia Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published by
 * the Free Software Foundation.
 *
 * 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 St, Fifth Floor, Boston, MA 02110-1301 USA
 */

/*
 * An utility to get UBI information.
 *
 * Author: Artem Bityutskiy
 */

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

#include <libubi.h>
#include "common.h"

#define PROGRAM_VERSION "1.1"
#define PROGRAM_NAME    "ubinfo"

/* The variables below are set by command line arguments */
struct args {
	int devn;
	int vol_id;
	int all;
	const char *node;
};

static struct args args = {
	.vol_id = -1,
	.devn = -1,
	.all = 0,
	.node = NULL,
};

static const char *doc = PROGRAM_NAME " version " PROGRAM_VERSION
			 " - a tool to print UBI information.";

static const char *optionsstr =
"-d, --devn=<UBI device number>  UBI device number to get information about\n"
"-n, --vol_id=<volume ID>        ID of UBI volume to print information about\n"
"-a, --all                       print information about all devices and volumes,\n"
"                                or about all volumes if the UBI device was\n"
"                                specified\n"
"-h, --help                      print help message\n"
"-V, --version                   print program version";

static const char *usage =
"Usage 1: " PROGRAM_NAME " [-d <UBI device number>] [-n <volume ID>] [-a] [-h] [-V] [--vol_id=<volume ID>]\n"
"\t\t[--devn <UBI device number>] [--all] [--help] [--version]\n"
"Usage 2: " PROGRAM_NAME " <UBI device node file name> [-a] [-h] [-V] [--all] [--help] [--version]\n"
"Usage 3: " PROGRAM_NAME " <UBI volume node file name> [-h] [-V] [--help] [--version]\n\n"
"Example 1: " PROGRAM_NAME " - (no arguments) print general UBI information\n"
"Example 2: " PROGRAM_NAME " -d 1 - print information about UBI device number 1\n"
"Example 3: " PROGRAM_NAME " /dev/ubi0 -a - print information about all volumes of UBI\n"
"           device /dev/ubi0\n"
"Example 4: " PROGRAM_NAME " /dev/ubi1_0 - print information about UBI volume /dev/ubi1_0\n"
"Example 5: " PROGRAM_NAME " -a - print all information\n";

static const struct option long_options[] = {
	{ .name = "devn",      .has_arg = 1, .flag = NULL, .val = 'd' },
	{ .name = "vol_id",    .has_arg = 1, .flag = NULL, .val = 'n' },
	{ .name = "all",       .has_arg = 0, .flag = NULL, .val = 'a' },
	{ .name = "help",      .has_arg = 0, .flag = NULL, .val = 'h' },
	{ .name = "version",   .has_arg = 0, .flag = NULL, .val = 'V' },
	{ NULL, 0, NULL, 0},
};

static int parse_opt(int argc, char * const argv[])
{
	while (1) {
		int key;
		char *endp;

		key = getopt_long(argc, argv, "an:d:hV", long_options, NULL);
		if (key == -1)
			break;

		switch (key) {
		case 'a':
			args.all = 1;
			break;

		case 'n':
			args.vol_id = strtoul(optarg, &endp, 0);
			if (*endp != '\0' || endp == optarg || args.vol_id < 0)
				return errmsg("bad volume ID: " "\"%s\"", optarg);
			break;

		case 'd':
			args.devn = strtoul(optarg, &endp, 0);
			if (*endp != '\0' || endp == optarg || args.devn < 0)
				return errmsg("bad UBI device number: \"%s\"", optarg);

			break;

		case 'h':
			fprintf(stderr, "%s\n\n", doc);
			fprintf(stderr, "%s\n\n", usage);
			fprintf(stderr, "%s\n", optionsstr);
			exit(EXIT_SUCCESS);

		case 'V':
			fprintf(stderr, "%s\n", PROGRAM_VERSION);
			exit(EXIT_SUCCESS);

		case ':':
			return errmsg("parameter is missing");

		default:
			fprintf(stderr, "Use -h for help\n");
			return -1;
		}
	}

	if (optind == argc - 1)
		args.node = argv[optind];
	else if (optind < argc)
		return errmsg("more then one UBI device specified (use -h for help)");

	return 0;
}

static int translate_dev(libubi_t libubi, const char *node)
{
	int err;

	err = ubi_probe_node(libubi, node);
	if (err == -1) {
		if (errno != ENODEV)
			return sys_errmsg("error while probing \"%s\"", node);
		return errmsg("\"%s\" does not correspond to any UBI device or volume", node);
	}

	if (err == 1) {
		struct ubi_dev_info dev_info;

		err = ubi_get_dev_info(libubi, node, &dev_info);
		if (err)
			return sys_errmsg("cannot get information about UBI device \"%s\"", node);

		args.devn = dev_info.dev_num;
	} else {
		struct ubi_vol_info vol_info;

		err = ubi_get_vol_info(libubi, node, &vol_info);
		if (err)
			return sys_errmsg("cannot get information about UBI volume \"%s\"", node);

		if (args.vol_id != -1)
			return errmsg("both volume character device node (\"%s\") and "
				      "volume ID (%d) are specify, use only one of them"
				      "(use -h for help)", node, args.vol_id);

		args.devn = vol_info.dev_num;
		args.vol_id = vol_info.vol_id;
	}

	return 0;
}

static int print_vol_info(libubi_t libubi, int dev_num, int vol_id)
{
	int err;
	struct ubi_vol_info vol_info;

	err = ubi_get_vol_info1(libubi, dev_num, vol_id, &vol_info);
	if (err)
		return sys_errmsg("cannot get information about UBI volume %d on ubi%d",
				  vol_id, dev_num);

	printf("Volume ID:   %d (on ubi%d)\n", vol_info.vol_id, vol_info.dev_num);
	printf("Type:        %s\n",
	       vol_info.type == UBI_DYNAMIC_VOLUME ?  "dynamic" : "static");
	printf("Alignment:   %d\n", vol_info.alignment);

	printf("Size:        %d LEBs (", vol_info.rsvd_lebs);
	ubiutils_print_bytes(vol_info.rsvd_bytes, 0);
	printf(")\n");

	if (vol_info.type == UBI_STATIC_VOLUME) {
		printf("Data bytes:  ");
		ubiutils_print_bytes(vol_info.data_bytes, 1);
		printf("\n");
	}
	printf("State:       %s\n", vol_info.corrupted ? "corrupted" : "OK");
	printf("Name:        %s\n", vol_info.name);
	printf("Character device major/minor: %d:%d\n",
	       vol_info.major, vol_info.minor);

	return 0;
}

static int print_dev_info(libubi_t libubi, int dev_num, int all)
{
	int i, err, first = 1;
	struct ubi_dev_info dev_info;
	struct ubi_vol_info vol_info;

	err = ubi_get_dev_info1(libubi, dev_num, &dev_info);
	if (err)
		return sys_errmsg("cannot get information about UBI device %d", dev_num);

	printf("ubi%d\n", dev_info.dev_num);
	printf("Volumes count:                           %d\n", dev_info.vol_count);
	printf("Logical eraseblock size:                 ");
	ubiutils_print_bytes(dev_info.leb_size, 0);
	printf("\n");

	printf("Total amount of logical eraseblocks:     %d (", dev_info.total_lebs);
	ubiutils_print_bytes(dev_info.total_bytes, 0);
	printf(")\n");

	printf("Amount of available logical eraseblocks: %d (", dev_info.avail_lebs);
	ubiutils_print_bytes(dev_info.avail_bytes, 0);
	printf(")\n");

	printf("Maximum count of volumes                 %d\n", dev_info.max_vol_count);
	printf("Count of bad physical eraseblocks:       %d\n", dev_info.bad_count);
	printf("Count of reserved physical eraseblocks:  %d\n", dev_info.bad_rsvd);
	printf("Current maximum erase counter value:     %lld\n", dev_info.max_ec);
	printf("Minimum input/output unit size:          %d %s\n",
	       dev_info.min_io_size, dev_info.min_io_size > 1 ? "bytes" : "byte");
	printf("Character device major/minor:            %d:%d\n",
	       dev_info.major, dev_info.minor);

	if (dev_info.vol_count == 0)
		return 0;

	printf("Present volumes:                         ");
	for (i = dev_info.lowest_vol_id;
	     i <= dev_info.highest_vol_id; i++) {
		err = ubi_get_vol_info1(libubi, dev_info.dev_num, i, &vol_info);
		if (err == -1) {
			if (errno == ENOENT)
				continue;

			return sys_errmsg("libubi failed to probe volume %d on ubi%d",
					  i, dev_info.dev_num);
		}

		if (!first)
			printf(", %d", i);
		else {
			printf("%d", i);
			first = 0;
		}
	}
	printf("\n");

	if (!all)
		return 0;

	first = 1;
	printf("\n");

	for (i = dev_info.lowest_vol_id;
	     i <= dev_info.highest_vol_id; i++) {
		if(!first)
			printf("-----------------------------------\n");
		err = ubi_get_vol_info1(libubi, dev_info.dev_num, i, &vol_info);
		if (err == -1) {
			if (errno == ENOENT)
				continue;

			return sys_errmsg("libubi failed to probe volume %d on ubi%d",
					  i, dev_info.dev_num);
		}
		first = 0;

		err = print_vol_info(libubi, dev_info.dev_num, i);
		if (err)
			return err;
	}

	return 0;
}

static int print_general_info(libubi_t libubi, int all)
{
	int i, err, first = 1;
	struct ubi_info ubi_info;
	struct ubi_dev_info dev_info;

	err = ubi_get_info(libubi, &ubi_info);
	if (err)
		return sys_errmsg("cannot get UBI information");

	printf("UBI version:                    %d\n", ubi_info.version);
	printf("Count of UBI devices:           %d\n", ubi_info.dev_count);
	if (ubi_info.ctrl_major != -1)
		printf("UBI control device major/minor: %d:%d\n",
		       ubi_info.ctrl_major, ubi_info.ctrl_minor);
	else
		printf("UBI control device is not supported by this kernel\n");

	if (ubi_info.dev_count == 0)
		return 0;

	printf("Present UBI devices:            ");
	for (i = ubi_info.lowest_dev_num;
	     i <= ubi_info.highest_dev_num; i++) {
		err = ubi_get_dev_info1(libubi, i, &dev_info);
		if (err == -1) {
			if (errno == ENOENT)
				continue;

			printf("\n");
			return sys_errmsg("libubi failed to probe UBI device %d", i);
		}

		if (!first)
			printf(", ubi%d", i);
		else {
			printf("ubi%d", i);
			first = 0;
		}
	}
	printf("\n");

	if (!all)
		return 0;

	first = 1;
	printf("\n");

	for (i = ubi_info.lowest_dev_num;
	     i <= ubi_info.highest_dev_num; i++) {
		if(!first)
			printf("\n===================================\n\n");
		first = 0;
		err = print_dev_info(libubi, i, all);
		if (err)
			return err;
	}
	return 0;
}

int main(int argc, char * const argv[])
{
	int err;
	libubi_t libubi;

	err = parse_opt(argc, argv);
	if (err)
		return -1;

	libubi = libubi_open();
	if (!libubi) {
		if (errno == 0)
			return errmsg("UBI is not present in the system");
		return sys_errmsg("cannot open libubi");
	}

	if (args.node) {
		/*
		 * A character device was specified, translate this into UBI
		 * device number and volume ID.
		 */
		err = translate_dev(libubi, args.node);
		if (err)
			goto out_libubi;
	}

	if (args.vol_id != -1 && args.devn == -1) {
		errmsg("volume ID is specified, but UBI device number is not "
		       "(use -h for help)\n");
		goto out_libubi;
	}

	if (args.devn != -1 && args.vol_id != -1) {
		print_vol_info(libubi, args.devn, args.vol_id);
		goto out;
	}

	if (args.devn == -1 && args.vol_id == -1)
		err = print_general_info(libubi, args.all);
	else if (args.devn != -1 && args.vol_id == -1)
		err = print_dev_info(libubi, args.devn, args.all);

	if (err)
		goto out_libubi;

out:
	libubi_close(libubi);
	return 0;

out_libubi:
	libubi_close(libubi);
	return -1;
}
