/**
 * 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 <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <systemd/sd-bus.h>
#include <systemd/sd-event.h>

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

static int callback(sd_bus_message *m, void *user, sd_bus_error *error)
{
	sd_event *loop = user;
	int r;
	char *property = NULL;

	r = sd_bus_message_skip(m, "s");
	if (r < 0)
	{
		fprintf(stderr, "Error skipping message fields: %s\n",
				strerror(-r));
		quit(r, loop);
		return r;
	}

	r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "{sv}");
	if (r < 0)
	{
		fprintf(stderr, "Error entering container: %s\n",
				strerror(-r));
		quit(r, loop);
		return r;
	}

	while ((r = sd_bus_message_enter_container(
				m,
				SD_BUS_TYPE_DICT_ENTRY,
				"sv")) > 0)
	{
		r = sd_bus_message_read(m, "s", &property);
		if (r < 0)
		{
			fprintf(stderr, "Error reading message: %s\n",
					strerror(-r));
			quit(r, loop);
			return r;
		}

		if (strcmp(property, "pgood"))
			continue;

		quit(0, loop);
		break;
	}

	return 0;
}

static int get_object(sd_bus *conn, const char *obj,
					  sd_bus_message **reply)
{
	sd_bus_message *request = NULL;
	int r, retry = 0;

	r = sd_bus_message_new_method_call(
		conn, &request, "xyz.openbmc_project.ObjectMapper",
		"/xyz/openbmc_project/object_mapper",
		"xyz.openbmc_project.ObjectMapper", "GetObject");
	if (r < 0)
		goto exit;

	r = sd_bus_message_append(request, "s", obj);
	if (r < 0)
		goto exit;
	r = sd_bus_message_append(request, "as", 0, NULL);
	if (r < 0)
		goto exit;

	while (true)
	{
		r = sd_bus_call(conn, request, 0, NULL, reply);
		if (r == -EBUSY || r == -ENOBUFS)
		{
			if (retry >= mapper_busy_retries)
				break;

			usleep(mapper_busy_delay_interval_usec * (1 << retry));
			++retry;
			continue;
		}
		break;
	}

	if (r < 0)
		goto exit;

exit:
	sd_bus_message_unref(request);

	return r;
}

static int get_service(sd_bus *conn, const char *obj, char **service)
{
	sd_bus_message *reply = NULL;
	const char *tmp;
	int r;

	r = get_object(conn, obj, &reply);
	if (r < 0)
		goto exit;

	r = sd_bus_message_enter_container(reply, 0, NULL);
	if (r < 0)
		goto exit;

	r = sd_bus_message_enter_container(reply, 0, NULL);
	if (r < 0)
		goto exit;

	r = sd_bus_message_read(reply, "s", &tmp);
	if (r < 0)
		goto exit;

	*service = strdup(tmp);

exit:
	sd_bus_message_unref(reply);

	return r;
}

int main(int argc, char *argv[])
{
	static const char *matchfmt =
		"type='signal',"
		"interface='org.freedesktop.DBus.Properties',"
		"member='PropertiesChanged',"
		"arg0='org.openbmc.control.Power',"
		"path='%s',"
		"sender='%s'";
	static const char *usage =
		"Usage: %s OBJECTPATH on|off\n";
	static const size_t LEN = 256;

	sd_bus *conn = NULL;
	sd_event *loop = NULL;
	sd_bus_slot *slot = NULL;
	sd_bus_error error = SD_BUS_ERROR_NULL;
	char *service = NULL;
	int r, dest = -1, state;
	char match[LEN];

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

	if (!strcmp(argv[2], "on"))
		dest = 1;
	if (!strcmp(argv[2], "off"))
		dest = 0;

	if (dest != 0 && dest != 1)
	{
		fprintf(stderr, usage, 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 = get_service(conn, argv[1], &service);
	if (r < 0)
	{
		fprintf(stderr, "Error obtaining host service: %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;
	}

	if (strlen(matchfmt) + strnlen(argv[1], LEN) > LEN)
	{
		r = -E2BIG;
		fprintf(stderr, "Error adding match rule: %s\n",
				strerror(-r));
		goto finish;
	}

	sprintf(match, matchfmt, argv[1], service);

	r = sd_bus_add_match(conn,
						 &slot,
						 match,
						 callback,
						 loop);
	if (r < 0)
	{
		fprintf(stderr, "Error adding match rule: %s\n",
				strerror(-r));
		goto finish;
	}

	r = sd_bus_get_property_trivial(conn,
									service,
									argv[1],
									"org.openbmc.control.Power",
									"pgood",
									&error,
									'i',
									&state);
	if (r < 0)
	{
		fprintf(stderr, "Error getting property: %s\n",
				strerror(-r));
		goto finish;
	}

	if (dest == state)
		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);
}
