/*
 * Copyright (C) 2005-2015 Red Hat, Inc. All rights reserved.
 *
 * This file is part of the device-mapper userspace tools.
 *
 * This copyrighted material is made available to anyone wishing to use,
 * modify, copy, or redistribute it subject to the terms and conditions
 * of the GNU Lesser General Public License v.2.1.
 *
 * You should have received a copy of the GNU Lesser 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
 */

#include "dmlib.h"
#include "libdm-common.h"

int dm_get_status_snapshot(struct dm_pool *mem, const char *params,
			   struct dm_status_snapshot **status)
{
	struct dm_status_snapshot *s;
	int r;

	if (!params) {
		log_error("Failed to parse invalid snapshot params.");
		return 0;
	}

	if (!(s = dm_pool_zalloc(mem, sizeof(*s)))) {
		log_error("Failed to allocate snapshot status structure.");
		return 0;
	}

	r = sscanf(params, FMTu64 "/" FMTu64 " " FMTu64,
		   &s->used_sectors, &s->total_sectors,
		   &s->metadata_sectors);

	if (r == 3 || r == 2)
		s->has_metadata_sectors = (r == 3);
	else if (!strcmp(params, "Invalid"))
		s->invalid = 1;
	else if (!strcmp(params, "Merge failed"))
		s->merge_failed = 1;
	else if (!strcmp(params, "Overflow"))
		s->overflow = 1;
	else {
		dm_pool_free(mem, s);
		log_error("Failed to parse snapshot params: %s.", params);
		return 0;
	}

	*status = s;

	return 1;
}

/*
 * Skip nr fields each delimited by a single space.
 * FIXME Don't assume single space.
 */
static const char *_skip_fields(const char *p, unsigned nr)
{
	while (p && nr-- && (p = strchr(p, ' ')))
		p++;

	return p;
}

/*
 * Count number of single-space delimited fields.
 * Number of fields is number of spaces plus one.
 */
static unsigned _count_fields(const char *p)
{
	unsigned nr = 1;

	if (!p || !*p)
		return 0;

	while ((p = _skip_fields(p, 1)))
		nr++;

	return nr;
}

/*
 * Various RAID status versions include:
 * Versions < 1.5.0 (4 fields):
 *   <raid_type> <#devs> <health_str> <sync_ratio>
 * Versions 1.5.0+  (6 fields):
 *   <raid_type> <#devs> <health_str> <sync_ratio> <sync_action> <mismatch_cnt>
 */
int dm_get_status_raid(struct dm_pool *mem, const char *params,
		       struct dm_status_raid **status)
{
	int i;
	unsigned num_fields;
	const char *p, *pp, *msg_fields = "";
	struct dm_status_raid *s = NULL;

	if ((num_fields = _count_fields(params)) < 4)
		goto_bad;

	/* Second field holds the device count */
	msg_fields = "<#devs> ";
	if (!(p = _skip_fields(params, 1)) || (sscanf(p, "%d", &i) != 1))
		goto_bad;

	msg_fields = "";
	if (!(s = dm_pool_zalloc(mem, sizeof(struct dm_status_raid))))
		goto_bad;

	if (!(s->raid_type = dm_pool_zalloc(mem, p - params)))
		goto_bad; /* memory is freed when pool is destroyed */

	if (!(s->dev_health = dm_pool_zalloc(mem, i + 1))) /* Space for health chars */
		goto_bad;

	msg_fields = "<raid_type> <#devices> <health_chars> and <sync_ratio> ";
	if (sscanf(params, "%s %u %s %" PRIu64 "/%" PRIu64,
		   s->raid_type,
		   &s->dev_count,
		   s->dev_health,
		   &s->insync_regions,
		   &s->total_regions) != 5)
		goto_bad;

	/*
	 * All pre-1.5.0 version parameters are read.  Now we check
	 * for additional 1.5.0+ parameters (i.e. num_fields at least 6).
	 *
	 * Note that 'sync_action' will be NULL (and mismatch_count
	 * will be 0) if the kernel returns a pre-1.5.0 status.
	 */
	if (num_fields < 6)
		goto out;

	msg_fields = "<sync_action> and <mismatch_cnt> ";

	/* Skip pre-1.5.0 params */
	if (!(p = _skip_fields(params, 4)) || !(pp = _skip_fields(p, 1)))
		goto_bad;

	if (!(s->sync_action = dm_pool_zalloc(mem, pp - p)))
		goto_bad;

	if (sscanf(p, "%s %" PRIu64, s->sync_action, &s->mismatch_count) != 2)
		goto_bad;

out:
	*status = s;

	return 1;

bad:
	log_error("Failed to parse %sraid params: %s", msg_fields, params);

	if (s)
		dm_pool_free(mem, s);

	*status = NULL;

	return 0;
}

/*
 * <metadata block size> <#used metadata blocks>/<#total metadata blocks>
 * <cache block size> <#used cache blocks>/<#total cache blocks>
 * <#read hits> <#read misses> <#write hits> <#write misses>
 * <#demotions> <#promotions> <#dirty> <#features> <features>*
 * <#core args> <core args>* <policy name> <#policy args> <policy args>*
 *
 * metadata block size      : Fixed block size for each metadata block in
 *                            sectors
 * #used metadata blocks    : Number of metadata blocks used
 * #total metadata blocks   : Total number of metadata blocks
 * cache block size         : Configurable block size for the cache device
 *                            in sectors
 * #used cache blocks       : Number of blocks resident in the cache
 * #total cache blocks      : Total number of cache blocks
 * #read hits               : Number of times a READ bio has been mapped
 *                            to the cache
 * #read misses             : Number of times a READ bio has been mapped
 *                            to the origin
 * #write hits              : Number of times a WRITE bio has been mapped
 *                            to the cache
 * #write misses            : Number of times a WRITE bio has been
 *                            mapped to the origin
 * #demotions               : Number of times a block has been removed
 *                            from the cache
 * #promotions              : Number of times a block has been moved to
 *                            the cache
 * #dirty                   : Number of blocks in the cache that differ
 *                            from the origin
 * #feature args            : Number of feature args to follow
 * feature args             : 'writethrough' (optional)
 * #core args               : Number of core arguments (must be even)
 * core args                : Key/value pairs for tuning the core
 *                            e.g. migration_threshold
 *			     *policy name              : Name of the policy
 * #policy args             : Number of policy arguments to follow (must be even)
 * policy args              : Key/value pairs
 *                            e.g. sequential_threshold
 */
int dm_get_status_cache(struct dm_pool *mem, const char *params,
			struct dm_status_cache **status)
{
	int i, feature_argc;
	char *str;
	const char *p, *pp;
	struct dm_status_cache *s;

	if (!(s = dm_pool_zalloc(mem, sizeof(struct dm_status_cache))))
		return_0;

	if (strstr(params, "Error")) {
		s->error = 1;
		s->fail = 1; /*  This is also I/O fail state */
		goto out;
	}

	if (strstr(params, "Fail")) {
		s->fail = 1;
		goto out;
	}

	/* Read in args that have definitive placement */
	if (sscanf(params,
		   " %" PRIu32
		   " %" PRIu64 "/%" PRIu64
		   " %" PRIu32
		   " %" PRIu64 "/%" PRIu64
		   " %" PRIu64 " %" PRIu64
		   " %" PRIu64 " %" PRIu64
		   " %" PRIu64 " %" PRIu64
		   " %" PRIu64
		   " %d",
		   &s->metadata_block_size,
		   &s->metadata_used_blocks, &s->metadata_total_blocks,
		   &s->block_size, /* AKA, chunk_size */
		   &s->used_blocks, &s->total_blocks,
		   &s->read_hits, &s->read_misses,
		   &s->write_hits, &s->write_misses,
		   &s->demotions, &s->promotions,
		   &s->dirty_blocks,
		   &feature_argc) != 14)
		goto bad;

	/* Now jump to "features" section */
	if (!(p = _skip_fields(params, 12)))
		goto bad;

	/* Read in features */
	for (i = 0; i < feature_argc; i++) {
		if (!strncmp(p, "writethrough ", 13))
			s->feature_flags |= DM_CACHE_FEATURE_WRITETHROUGH;
		else if (!strncmp(p, "writeback ", 10))
			s->feature_flags |= DM_CACHE_FEATURE_WRITEBACK;
		else if (!strncmp(p, "passthrough ", 11))
			s->feature_flags |= DM_CACHE_FEATURE_PASSTHROUGH;
		else
			log_error("Unknown feature in status: %s", params);

		if (!(p = _skip_fields(p, 1)))
			goto bad;
	}

	/* Read in core_args. */
	if (sscanf(p, "%d ", &s->core_argc) != 1)
		goto bad;
	if ((s->core_argc > 0) &&
	    (!(s->core_argv = dm_pool_zalloc(mem, sizeof(char *) * s->core_argc)) ||
	     !(p = _skip_fields(p, 1)) ||
	     !(str = dm_pool_strdup(mem, p)) ||
	     !(p = _skip_fields(p, (unsigned) s->core_argc)) ||
	     (dm_split_words(str, s->core_argc, 0, s->core_argv) != s->core_argc)))
		goto bad;

	/* Read in policy args */
	pp = p;
	if (!(p = _skip_fields(p, 1)) ||
	    !(s->policy_name = dm_pool_zalloc(mem, (p - pp))))
		goto bad;
	if (sscanf(pp, "%s %d", s->policy_name, &s->policy_argc) != 2)
		goto bad;
	if (s->policy_argc &&
	    (!(s->policy_argv = dm_pool_zalloc(mem, sizeof(char *) * s->policy_argc)) ||
	     !(p = _skip_fields(p, 1)) ||
	     !(str = dm_pool_strdup(mem, p)) ||
	     (dm_split_words(str, s->policy_argc, 0, s->policy_argv) != s->policy_argc)))
		goto bad;

	/* TODO: improve this parser */
	if (strstr(p, " ro"))
		s->read_only = 1;

	if (strstr(p, " needs_check"))
		s->needs_check = 1;
out:
	*status = s;
	return 1;

bad:
	log_error("Failed to parse cache params: %s", params);
	dm_pool_free(mem, s);
	*status = NULL;

	return 0;
}

int parse_thin_pool_status(const char *params, struct dm_status_thin_pool *s)
{
	int pos;

	if (!params) {
		log_error("Failed to parse invalid thin params.");
		return 0;
	}

	if (strstr(params, "Error")) {
		s->error = 1;
		s->fail = 1; /*  This is also I/O fail state */
		return 1;
	}

	if (strstr(params, "Fail")) {
		s->fail = 1;
		return 1;
	}

	/* FIXME: add support for held metadata root */
	if (sscanf(params, FMTu64 " " FMTu64 "/" FMTu64 " " FMTu64 "/" FMTu64 "%n",
		   &s->transaction_id,
		   &s->used_metadata_blocks,
		   &s->total_metadata_blocks,
		   &s->used_data_blocks,
		   &s->total_data_blocks, &pos) < 5) {
		log_error("Failed to parse thin pool params: %s.", params);
		return 0;
	}

	/* New status flags */
	if (strstr(params + pos, "no_discard_passdown"))
		s->discards = DM_THIN_DISCARDS_NO_PASSDOWN;
	else if (strstr(params + pos, "ignore_discard"))
		s->discards = DM_THIN_DISCARDS_IGNORE;
	else /* default discard_passdown */
		s->discards = DM_THIN_DISCARDS_PASSDOWN;

	/* Default is 'writable' (rw) data */
	if (strstr(params + pos, "out_of_data_space"))
		s->out_of_data_space = 1;
	else if (strstr(params + pos, "ro "))
		s->read_only = 1;

	/* Default is 'queue_if_no_space' */
	if (strstr(params + pos, "error_if_no_space"))
		s->error_if_no_space = 1;

	if (strstr(params + pos, "needs_check"))
		s->needs_check = 1;

	return 1;
}

int dm_get_status_thin_pool(struct dm_pool *mem, const char *params,
			    struct dm_status_thin_pool **status)
{
	struct dm_status_thin_pool *s;

	if (!(s = dm_pool_zalloc(mem, sizeof(struct dm_status_thin_pool)))) {
		log_error("Failed to allocate thin_pool status structure.");
		return 0;
	}

	if (!parse_thin_pool_status(params, s)) {
		dm_pool_free(mem, s);
		return_0;
	}

	*status = s;

	return 1;
}

int dm_get_status_thin(struct dm_pool *mem, const char *params,
		       struct dm_status_thin **status)
{
	struct dm_status_thin *s;

	if (!(s = dm_pool_zalloc(mem, sizeof(struct dm_status_thin)))) {
		log_error("Failed to allocate thin status structure.");
		return 0;
	}

	if (strchr(params, '-')) {
		/* nothing to parse */
	} else if (strstr(params, "Fail")) {
		s->fail = 1;
	} else if (sscanf(params, FMTu64 " " FMTu64,
		   &s->mapped_sectors,
		   &s->highest_mapped_sector) != 2) {
		dm_pool_free(mem, s);
		log_error("Failed to parse thin params: %s.", params);
		return 0;
	}

	*status = s;

	return 1;
}

/*
 * dm core parms:	     0 409600 mirror
 * Mirror core parms:	     2 253:4 253:5 400/400
 * New-style failure params: 1 AA
 * New-style log params:     3 cluster 253:3 A
 *			 or  3 disk 253:3 A
 *			 or  1 core
 */
#define DM_MIRROR_MAX_IMAGES 8 /* limited by kernel DM_KCOPYD_MAX_REGIONS */

int dm_get_status_mirror(struct dm_pool *mem, const char *params,
			 struct dm_status_mirror **status)
{
	struct dm_status_mirror *s;
	const char *p, *pos = params;
	unsigned num_devs, argc, i;
	int used;

	if (!(s = dm_pool_zalloc(mem, sizeof(*s)))) {
		log_error("Failed to alloc mem pool to parse mirror status.");
		return 0;
	}

	if (sscanf(pos, "%u %n", &num_devs, &used) != 1)
		goto_out;
	pos += used;

	if (num_devs > DM_MIRROR_MAX_IMAGES) {
		log_error(INTERNAL_ERROR "More then " DM_TO_STRING(DM_MIRROR_MAX_IMAGES)
			  " reported in mirror status.");
		goto out;
	}

	if (!(s->devs = dm_pool_alloc(mem, num_devs * sizeof(*(s->devs))))) {
		log_error("Allocation of devs failed.");
		goto out;
	}

	for (i = 0; i < num_devs; ++i, pos += used)
		if (sscanf(pos, "%u:%u %n",
			   &(s->devs[i].major), &(s->devs[i].minor), &used) != 2)
			goto_out;

	if (sscanf(pos, FMTu64 "/" FMTu64 "%n",
		   &s->insync_regions, &s->total_regions, &used) != 2)
		goto_out;
	pos += used;

	if (sscanf(pos, "%u %n", &argc, &used) != 1)
		goto_out;
	pos += used;

	for (i = 0; i < num_devs ; ++i)
		s->devs[i].health = pos[i];

	if (!(pos = _skip_fields(pos, argc)))
		goto_out;

	if (sscanf(pos, "%u %n", &argc, &used) != 1)
		goto_out;
	pos += used;

	if (argc == 1) {
		/* core, cluster-core */
		if (!(s->log_type = dm_pool_strdup(mem, pos))) {
			log_error("Allocation of log type string failed.");
			goto out;
		}
	} else {
		if (!(p = _skip_fields(pos, 1)))
			goto_out;

		/* disk, cluster-disk */
		if (!(s->log_type = dm_pool_strndup(mem, pos, p - pos - 1))) {
			log_error("Allocation of log type string failed.");
			goto out;
		}
		pos = p;

		if ((argc > 2) && !strcmp(s->log_type, "disk")) {
			s->log_count = argc - 2;

			if (!(s->logs = dm_pool_alloc(mem, s->log_count * sizeof(*(s->logs))))) {
				log_error("Allocation of logs failed.");
				goto out;
			}

			for (i = 0; i < s->log_count; ++i, pos += used)
				if (sscanf(pos, "%u:%u %n",
					   &s->logs[i].major, &s->logs[i].minor, &used) != 2)
					goto_out;

			for (i = 0; i < s->log_count; ++i)
				s->logs[i].health = pos[i];
		}
	}

	s->dev_count = num_devs;
	*status = s;

	return 1;
out:
	log_error("Failed to parse mirror status %s.", params);
	dm_pool_free(mem, s);
	*status = NULL;

	return 0;
}
