/*
 * Copyright (C) 2011-2014 Red Hat, Inc.
 *
 * This file is part of LVM2.
 *
 * 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 General Public License v.2.
 *
 * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
 */
#include "tool.h"

#include "lvmetad-client.h"
#include "label.h"
#include "lvmcache.h"
#include "metadata.h"

const char *uuid1 = "abcd-efgh";
const char *uuid2 = "bbcd-efgh";
const char *vgid = "yada-yada";
const char *uuid3 = "cbcd-efgh";

const char *metadata2 = "{\n"
	"id = \"yada-yada\"\n"
	"seqno = 15\n"
	"status = [\"READ\", \"WRITE\"]\n"
	"flags = []\n"
	"extent_size = 8192\n"
	"physical_volumes {\n"
	"    pv0 {\n"
	"        id = \"abcd-efgh\"\n"
	"    }\n"
	"    pv1 {\n"
	"        id = \"bbcd-efgh\"\n"
	"    }\n"
	"    pv2 {\n"
	"        id = \"cbcd-efgh\"\n"
	"    }\n"
	"}\n"
	"}\n";

void _handle_reply(daemon_reply reply) {
	const char *repl = daemon_reply_str(reply, "response", NULL);
	const char *status = daemon_reply_str(reply, "status", NULL);
	const char *vgid = daemon_reply_str(reply, "vgid", NULL);

	fprintf(stderr, "[C] REPLY: %s\n", repl);
	if (!strcmp(repl, "failed"))
		fprintf(stderr, "[C] REASON: %s\n", daemon_reply_str(reply, "reason", "unknown"));
	if (vgid)
		fprintf(stderr, "[C] VGID: %s\n", vgid);
	if (status)
		fprintf(stderr, "[C] STATUS: %s\n", status);
	daemon_reply_destroy(reply);
}

void _pv_add(daemon_handle h, const char *uuid, const char *metadata)
{
	daemon_reply reply = daemon_send_simple(h, "pv_add", "uuid = %s", uuid,
						             "metadata = %b", metadata,
						             NULL);
	_handle_reply(reply);
}

int scan(daemon_handle h, char *fn) {
	struct device *dev = dev_cache_get(fn, NULL);

	struct label *label;
	if (!label_read(dev, &label, 0)) {
		fprintf(stderr, "[C] no label found on %s\n", fn);
		return;
	}

	char uuid[64];
	if (!id_write_format(dev->pvid, uuid, 64)) {
		fprintf(stderr, "[C] Failed to format PV UUID for %s", dev_name(dev));
		return;
	}
	fprintf(stderr, "[C] found PV: %s\n", uuid);
	struct lvmcache_info *info = (struct lvmcache_info *) label->info;
	struct physical_volume pv = { 0, };

	if (!(info->fmt->ops->pv_read(info->fmt, dev_name(dev), &pv, 0))) {
		fprintf(stderr, "[C] Failed to read PV %s", dev_name(dev));
		return;
	}

	struct format_instance_ctx fic;
	struct format_instance *fid = info->fmt->ops->create_instance(info->fmt, &fic);
	struct metadata_area *mda;
	struct volume_group *vg = NULL;
	dm_list_iterate_items(mda, &info->mdas) {
		struct volume_group *this = mda->ops->vg_read(fid, "", mda);
		if (this && !vg || this->seqno > vg->seqno)
			vg = this;
	}
	if (vg) {
		char *buf = NULL;
		/* TODO. This is not entirely correct, since export_vg_to_buffer
		 * adds trailing garbage to the buffer. We may need to use
		 * export_vg_to_config_tree and format the buffer ourselves. It
		 * does, however, work for now, since the garbage is well
		 * formatted and has no conflicting keys with the rest of the
		 * request.  */
		export_vg_to_buffer(vg, &buf);
		daemon_reply reply =
			daemon_send_simple(h, "pv_add", "uuid = %s", uuid,
					      "metadata = %b", strchr(buf, '{'),
					      NULL);
		_handle_reply(reply);
	}
}

void _dump_vg(daemon_handle h, const char *uuid)
{
	daemon_reply reply = daemon_send_simple(h, "vg_by_uuid", "uuid = %s", uuid, NULL);
	fprintf(stderr, "[C] reply buffer: %s\n", reply.buffer);
	daemon_reply_destroy(reply);
}

int main(int argc, char **argv) {
	daemon_handle h = lvmetad_open();
	/* FIXME Missing error path */

	if (argc > 1) {
		int i;
		struct cmd_context *cmd = create_toolcontext(0, NULL, 0, 0, 1, 1);
		for (i = 1; i < argc; ++i) {
			const char *uuid = NULL;
			scan(h, argv[i]);
		}
		destroy_toolcontext(cmd);
		/* FIXME Missing lvmetad_close() */
		return 0;
	}

	_pv_add(h, uuid1, NULL);
	_pv_add(h, uuid2, metadata2);
	_dump_vg(h, vgid);
	_pv_add(h, uuid3, NULL);

	daemon_close(h);	/* FIXME lvmetad_close? */
	return 0;
}
