/**
 * Copyright 2016 IBM Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <systemd/sd-bus.h>
#include <systemd/sd-event.h>
#include "mapper.h"

static int call_main(int argc, char *argv[])
{
	int r;
	sd_bus *conn = NULL;
	char *service = NULL;
	sd_bus_message *m = NULL, *reply = NULL;
	sd_bus_error error = SD_BUS_ERROR_NULL;

	if(argc < 5) {
		fprintf(stderr, "Usage: %s call OBJECTPATH INTERFACE "
				"METHOD [SIGNATURE [ARGUMENT...]\n", argv[0]);
		r = -1;
		goto finish;
	}

	r = sd_bus_default_system(&conn);
	if(r < 0) {
		fprintf(stderr, "Error connecting to system bus: %s\n",
				strerror(-r));
		goto finish;
	}

	r = mapper_get_service(conn, argv[2], &service);
	if(r < 0) {
		fprintf(stderr, "Error finding '%s' service: %s\n",
				argv[2], strerror(-r));
		goto finish;
	}

	r = sd_bus_message_new_method_call(
			conn, &m, service, argv[2], argv[3], argv[4]);
	if(r < 0) {
		fprintf(stderr, "Error populating message: %s\n",
				strerror(-r));
		goto finish;
	}

	if(argc > 5) {
		char **p;
		p = argv + 6;
		r = sd_bus_message_append_cmdline(m, argv[5], &p);
		if(r < 0) {
			fprintf(stderr, "Error appending method arguments: %s\n",
					strerror(-r));
			goto finish;
		}
	}

	r = sd_bus_call(conn, m, 0, &error, &reply);
	if(r < 0) {
		fprintf(stderr, "Error invoking method: %s\n",
				strerror(-r));
		goto finish;
	}

finish:
	exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
}

static void quit(int r, void *loop)
{
	sd_event_exit((sd_event *)loop, r);
}

static int wait_main(int argc, char *argv[])
{
	int r;
	sd_bus *conn = NULL;
	sd_event *loop = NULL;
	mapper_async_wait *wait = NULL;

	if(argc < 3) {
		fprintf(stderr, "Usage: %s wait OBJECTPATH...\n", argv[0]);
		exit(EXIT_FAILURE);
	}

	r = sd_bus_default_system(&conn);
	if(r < 0) {
		fprintf(stderr, "Error connecting to system bus: %s\n",
				strerror(-r));
		goto finish;
	}

	r = sd_event_default(&loop);
	if (r < 0) {
		fprintf(stderr, "Error obtaining event loop: %s\n",
				strerror(-r));

		goto finish;
	}

	r = sd_bus_attach_event(conn, loop, SD_EVENT_PRIORITY_NORMAL);
	if (r < 0) {
		fprintf(stderr, "Failed to attach system "
				"bus to event loop: %s\n",
				strerror(-r));
		goto finish;
	}

	r = mapper_wait_async(conn, loop, argv+2, quit, loop, &wait);
	if(r < 0) {
		fprintf(stderr, "Error configuring waitlist: %s\n",
				strerror(-r));
		goto finish;
	}

	r = sd_event_loop(loop);
	if(r < 0) {
		fprintf(stderr, "Error starting event loop: %s\n",
				strerror(-r));
		goto finish;
	}

finish:
	exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
}

static int subtree_main(int argc, char *argv[])
{
	int r = 0;
	int op = 0;
	static const char* token = ":";
	char* tmp = NULL;
	char* namespace = NULL;
	char* interface = NULL;
	sd_bus *conn = NULL;
	sd_event *loop = NULL;
	mapper_async_subtree *subtree = NULL;

	if (argc != 3) {
		fprintf(stderr, "Usage: %s subtree-remove "
				"NAMESPACE%sINTERFACE\n", argv[0], token);
		exit(EXIT_FAILURE);
	}

	op = MAPPER_OP_REMOVE;

	namespace = strtok_r(argv[2], token, &tmp);
	interface = strtok_r(NULL, token, &tmp);
	if ((namespace == NULL) || (interface == NULL)) {
		fprintf(stderr, "Token '%s' was not found in '%s'\n", token, argv[2]);
		exit(EXIT_FAILURE);
	}

	r = sd_bus_default_system(&conn);
	if(r < 0) {
		fprintf(stderr, "Error connecting to system bus: %s\n",
				strerror(-r));
		goto finish;
	}

	r = sd_event_default(&loop);
	if (r < 0) {
		fprintf(stderr, "Error obtaining event loop: %s\n",
				strerror(-r));
		goto finish;
	}

	r = sd_bus_attach_event(conn, loop, SD_EVENT_PRIORITY_NORMAL);
	if (r < 0) {
		fprintf(stderr, "Failed to attach system bus to event loop: %s\n",
				strerror(-r));
		goto finish;
	}

	r = mapper_subtree_async(conn, loop, namespace, interface, quit, loop,
				&subtree, op);
	if(r < 0) {
		fprintf(stderr, "Error configuring subtree list: %s\n",
				strerror(-r));
		goto finish;
	}

	r = sd_event_loop(loop);
	if(r < 0) {
		fprintf(stderr, "Error starting event loop: %s\n",
				strerror(-r));
		goto finish;
	}

finish:
	exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
}

/* print out the distinct dbus service name for the input dbus path */
static int get_service_main(int argc, char *argv[])
{
	int r;
	sd_bus *conn = NULL;
	char *service = NULL;

	if(argc != 3) {
		fprintf(stderr, "Usage: %s get-service OBJECTPATH\n",
				argv[0]);
		exit(EXIT_FAILURE);
	}

	r = sd_bus_default_system(&conn);
	if(r < 0) {
		fprintf(stderr, "Error connecting to system bus: %s\n",
				strerror(-r));
		goto finish;
	}

	r = mapper_get_service(conn, argv[2], &service);
	if(r < 0) {
		fprintf(stderr, "Error finding '%s' service: %s\n",
				argv[2], strerror(-r));
		goto finish;
	}

	printf("%s\n", service);


finish:
	exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
}

int main(int argc, char *argv[])
{
	static const char *usage =
		"Usage: %s {COMMAND} ...\n"
		"\nCOMMANDS:\n"
		"  call           invoke the specified method\n"
		"  wait           wait for the specified objects to appear on the DBus\n"
		"  subtree-remove\n"
		"                 wait until the specified interface is not present\n"
		"                 in any of the subtrees of the specified namespace\n"
		"  get-service    return the service identifier for input path\n";

	if(argc < 2) {
		fprintf(stderr, usage, argv[0]);
		exit(EXIT_FAILURE);
	}

	if(!strcmp(argv[1], "call"))
		call_main(argc, argv);
	if(!strcmp(argv[1], "wait"))
		wait_main(argc, argv);
	if(!strcmp(argv[1], "subtree-remove"))
		subtree_main(argc, argv);
	if(!strcmp(argv[1], "get-service"))
		get_service_main(argc, argv);

	fprintf(stderr, usage, argv[0]);
	exit(EXIT_FAILURE);
}
