/*
 * Copyright (c) 2014-2016, Intel Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU Lesser General Public License,
 * version 2.1, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 * more details.
 */
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <syslog.h>
#include <libkmod.h>
#include <util/log.h>
#include <util/sysfs.h>
#include <linux/version.h>

#include <ccan/array_size/array_size.h>
#include <ndctl/libndctl.h>
#include <builtin.h>
#include <ndctl.h>
#include <test.h>

#define DIMM_PATH "/sys/devices/platform/nfit_test.0/nfit_test_dimm/test_dimm0"

static int reset_bus(struct ndctl_bus *bus)
{
	struct ndctl_region *region;
	struct ndctl_dimm *dimm;

	/* disable all regions so that set_config_data commands are permitted */
	ndctl_region_foreach(bus, region)
		ndctl_region_disable_invalidate(region);

	ndctl_dimm_foreach(bus, dimm) {
		if (!ndctl_dimm_read_labels(dimm))
			return -ENXIO;
		ndctl_dimm_disable(dimm);
		ndctl_dimm_init_labels(dimm, NDCTL_NS_VERSION_1_2);
		ndctl_dimm_enable(dimm);
	}

	/* set regions back to their default state */
	ndctl_region_foreach(bus, region)
		ndctl_region_enable(region);
	return 0;
}

static int set_dimm_response(const char *dimm_path, int cmd, int error_code,
		struct log_ctx *log_ctx)
{
	char path[1024], buf[SYSFS_ATTR_SIZE];
	int rc;

	if (error_code) {
		sprintf(path, "%s/fail_cmd", dimm_path);
		sprintf(buf, "%#x\n", 1 << cmd);
		rc = __sysfs_write_attr(log_ctx, path, buf);
		if (rc)
			goto out;
		sprintf(path, "%s/fail_cmd_code", dimm_path);
		sprintf(buf, "%d\n", error_code);
		rc = __sysfs_write_attr(log_ctx, path, buf);
		if (rc)
			goto out;
	} else {
		sprintf(path, "%s/fail_cmd", dimm_path);
		sprintf(buf, "0\n");
		rc = __sysfs_write_attr(log_ctx, path, buf);
		if (rc)
			goto out;
	}
out:
	if (rc < 0)
		fprintf(stderr, "%s failed, cmd: %d code: %d\n",
				__func__, cmd, error_code);
	return 0;
}

static int dimms_disable(struct ndctl_bus *bus)
{
	struct ndctl_dimm *dimm;

	ndctl_dimm_foreach(bus, dimm) {
		int rc = ndctl_dimm_disable(dimm);

		if (rc) {
			fprintf(stderr, "dimm: %s failed to disable: %d\n",
				ndctl_dimm_get_devname(dimm), rc);
			return rc;
		}
	}
	return 0;
}

static int test_dimms_enable(struct ndctl_bus *bus, struct ndctl_dimm *victim,
		bool expect)
{
	struct ndctl_dimm *dimm;

	ndctl_dimm_foreach(bus, dimm) {
		int rc = ndctl_dimm_enable(dimm);

		if (((expect != (rc == 0)) && (dimm == victim))
				|| (rc && dimm != victim)) {
			bool __expect = true;

			if (dimm == victim)
				__expect = expect;
			fprintf(stderr, "fail expected %s enable %s victim: %s rc: %d\n",
					ndctl_dimm_get_devname(dimm),
					__expect ? "success" : "failure",
					ndctl_dimm_get_devname(victim), rc);
			return -ENXIO;
		}
	}
	return 0;
}

static int test_regions_enable(struct ndctl_bus *bus,
		struct ndctl_dimm *victim, struct ndctl_region *victim_region,
		bool region_expect, int namespace_count)
{
	struct ndctl_region *region;

	ndctl_region_foreach(bus, region) {
		struct ndctl_namespace *ndns;
		struct ndctl_dimm *dimm;
		bool has_victim = false;
		int rc, count = 0;

		ndctl_dimm_foreach_in_region(region, dimm) {
			if (dimm == victim) {
				has_victim = true;
				break;
			}
		}

		rc = ndctl_region_enable(region);
		fprintf(stderr, "region: %s enable: %d has_victim: %d\n",
				ndctl_region_get_devname(region), rc, has_victim);
		if (((region_expect != (rc == 0)) && has_victim)
				|| (rc && !has_victim)) {
			bool __expect = true;

			if (has_victim)
				__expect = region_expect;
			fprintf(stderr, "%s: fail expected enable: %s with %s\n",
					ndctl_region_get_devname(region),
					__expect ? "success" : "failure",
					ndctl_dimm_get_devname(victim));
			return -ENXIO;
		}
		if (region != victim_region)
			continue;
		ndctl_namespace_foreach(region, ndns) {
			if (ndctl_namespace_is_enabled(ndns)) {
				fprintf(stderr, "%s: enabled, expected disabled\n",
						ndctl_namespace_get_devname(ndns));
				return -ENXIO;
			}
			fprintf(stderr, "%s: %s: size: %lld\n", __func__,
					ndctl_namespace_get_devname(ndns),
					ndctl_namespace_get_size(ndns));
			count++;
		}
		if (count != namespace_count) {
			fprintf(stderr, "%s: fail expected %d namespaces got %d\n",
					ndctl_region_get_devname(region),
					namespace_count, count);
			return -ENXIO;
		}
	}
	return 0;
}

static int do_test(struct ndctl_ctx *ctx, struct ndctl_test *test)
{
	struct ndctl_bus *bus = ndctl_bus_get_by_provider(ctx, "nfit_test.0");
	struct ndctl_region *region, *victim_region = NULL;
	struct ndctl_dimm *dimm, *victim = NULL;
	char path[1024], buf[SYSFS_ATTR_SIZE];
	struct log_ctx log_ctx;
	unsigned int handle;
	int rc, err = 0;

	if (!ndctl_test_attempt(test, KERNEL_VERSION(4, 9, 0)))
		return 77;

	if (!bus)
		return -ENXIO;

	log_init(&log_ctx, "test/dsm-fail", "NDCTL_TEST");

	if (reset_bus(bus)) {
		fprintf(stderr, "failed to read labels\n");
		return -ENXIO;
	}

	sprintf(path, "%s/handle", DIMM_PATH);
	rc = __sysfs_read_attr(&log_ctx, path, buf);
	if (rc) {
		fprintf(stderr, "failed to retrieve test dimm handle\n");
		return -ENXIO;
	}

	handle = strtoul(buf, NULL, 0);

	ndctl_dimm_foreach(bus, dimm)
		if (ndctl_dimm_get_handle(dimm) == handle) {
			victim = dimm;
			break;
		}

	if (!victim) {
		fprintf(stderr, "failed to find victim dimm\n");
		return -ENXIO;
	}
	fprintf(stderr, "victim: %s\n", ndctl_dimm_get_devname(victim));

	ndctl_region_foreach(bus, region) {
		if (ndctl_region_get_type(region) != ND_DEVICE_REGION_PMEM)
			continue;
		ndctl_dimm_foreach_in_region(region, dimm) {
			const char *argv[] = {
				"__func__", "-v", "-r",
				ndctl_region_get_devname(region),
				"-s", "4M", "-m", "raw",
			};
			struct ndctl_namespace *ndns;
			int count, i;

			if (dimm != victim)
				continue;
			/*
			 * Validate that we only have the one seed
			 * namespace, and then create one so that we can
			 * verify namespace enumeration while locked.
			 */
			count = 0;
			ndctl_namespace_foreach(region, ndns)
				count++;
			if (count != 1) {
				fprintf(stderr, "%s: found %d namespaces expected 1\n",
						ndctl_region_get_devname(region),
						count);
				rc = -ENXIO;
				goto out;
			}
			if (ndctl_region_get_size(region)
					!= ndctl_region_get_available_size(region)) {
				fprintf(stderr, "%s: expected empty region\n",
						ndctl_region_get_devname(region));
				rc = -ENXIO;
				goto out;
			}
			for (i = 0; i < 2; i++) {
				builtin_xaction_namespace_reset();
				rc = cmd_create_namespace(ARRAY_SIZE(argv), argv,
						ndctl_region_get_ctx(region));
				if (rc) {
					fprintf(stderr, "%s: failed to create namespace\n",
							ndctl_region_get_devname(region));
					rc = -ENXIO;
					goto out;
				}
			}
			victim_region = region;
		}
		if (victim_region)
			break;
	}

	/* disable all regions so that we can disable a dimm */
	ndctl_region_foreach(bus, region)
		ndctl_region_disable_invalidate(region);

	rc = dimms_disable(bus);
	if (rc)
		goto out;


	rc = set_dimm_response(DIMM_PATH, ND_CMD_GET_CONFIG_SIZE, -EACCES,
			&log_ctx);
	if (rc)
		goto out;
	fprintf(stderr, "%s:%d\n", __func__, __LINE__);
	rc = test_dimms_enable(bus, victim, true);
	if (rc)
		goto out;
	fprintf(stderr, "%s:%d\n", __func__, __LINE__);
	rc = test_regions_enable(bus, victim, victim_region, true, 2);
	if (rc)
		goto out;
	fprintf(stderr, "%s:%d\n", __func__, __LINE__);
	rc = set_dimm_response(DIMM_PATH, ND_CMD_GET_CONFIG_SIZE, 0, &log_ctx);
	if (rc)
		goto out;

	ndctl_region_foreach(bus, region)
		ndctl_region_disable_invalidate(region);
	fprintf(stderr, "%s:%d\n", __func__, __LINE__);
	rc = dimms_disable(bus);
	if (rc)
		goto out;
	fprintf(stderr, "%s:%d\n", __func__, __LINE__);

	rc = set_dimm_response(DIMM_PATH, ND_CMD_GET_CONFIG_DATA, -EACCES,
			&log_ctx);
	if (rc)
		goto out;
	fprintf(stderr, "%s:%d\n", __func__, __LINE__);
	rc = test_dimms_enable(bus, victim, false);
	if (rc)
		goto out;
	fprintf(stderr, "%s:%d\n", __func__, __LINE__);
	rc = test_regions_enable(bus, victim, victim_region, false, 0);
	if (rc)
		goto out;
	fprintf(stderr, "%s:%d\n", __func__, __LINE__);
	rc = set_dimm_response(DIMM_PATH, ND_CMD_GET_CONFIG_DATA, 0, &log_ctx);
	if (rc)
		goto out;
	fprintf(stderr, "%s:%d\n", __func__, __LINE__);
	rc = dimms_disable(bus);
	if (rc)
		goto out;
	fprintf(stderr, "%s:%d\n", __func__, __LINE__);

 out:
	err = rc;
	sprintf(path, "%s/fail_cmd", DIMM_PATH);
	sprintf(buf, "0\n");
	rc = __sysfs_write_attr(&log_ctx, path, buf);
	if (rc)
		fprintf(stderr, "%s: failed to clear fail_cmd mask\n",
				ndctl_dimm_get_devname(victim));
	rc = ndctl_dimm_enable(victim);
	if (rc) {
		fprintf(stderr, "failed to enable victim: %s after clearing error\n",
				ndctl_dimm_get_devname(victim));
		rc = -ENXIO;
	}
	reset_bus(bus);

	if (rc)
		err = rc;
	return err;
}

int test_dsm_fail(int loglevel, struct ndctl_test *test, struct ndctl_ctx *ctx)
{
	struct kmod_module *mod;
	struct kmod_ctx *kmod_ctx;
	int result = EXIT_FAILURE, err;

	ndctl_set_log_priority(ctx, loglevel);
	err = nfit_test_init(&kmod_ctx, &mod, NULL, loglevel, test);
	if (err < 0) {
		result = 77;
		ndctl_test_skip(test);
		fprintf(stderr, "%s unavailable skipping tests\n",
				"nfit_test");
		return result;
	}

	result = do_test(ctx, test);
	kmod_module_remove_module(mod, 0);

	kmod_unref(kmod_ctx);
	return result;
}

int __attribute__((weak)) main(int argc, char *argv[])
{
	struct ndctl_test *test = ndctl_test_new(0);
	struct ndctl_ctx *ctx;
	int rc;

	if (!test) {
		fprintf(stderr, "failed to initialize test\n");
		return EXIT_FAILURE;
	}

	rc = ndctl_new(&ctx);
	if (rc)
		return ndctl_test_result(test, rc);
	rc = test_dsm_fail(LOG_DEBUG, test, ctx);
	ndctl_unref(ctx);
	return ndctl_test_result(test, rc);
}
