/**
 * 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 <string.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <sys/timerfd.h>
#include <systemd/sd-bus.h>
#include <systemd/sd-event.h>
#include "mapper.h"

static const char *async_wait_introspection_match =
	"type='signal',"
	"sender='xyz.openbmc_project.ObjectMapper',"
	"interface='xyz.openbmc_project.ObjectMapper.Private',"
	"member='IntrospectionComplete'";

static const char *async_wait_interfaces_added_match =
	"type='signal',"
	"interface='org.freedesktop.DBus.ObjectManager',"
	"member='InterfacesAdded'";

static const char *interfaces_removed_match =
	"type='signal',"
	"interface='org.freedesktop.DBus.ObjectManager',"
	"member='InterfacesRemoved'";

static const int mapper_busy_retries = 5;
static const uint64_t mapper_busy_delay_interval_usec = 1000000;

struct mapper_async_wait
{
	char **objs;
	void (*callback)(int, void *);
	void *userdata;
	sd_event *loop;
	sd_bus *conn;
	sd_bus_slot *introspection_slot;
	sd_bus_slot *intf_slot;
	int *status;
	int count;
	int finished;
	int r;
};

struct async_wait_callback_data
{
	mapper_async_wait *wait;
	const char *path;
	sd_event_source *event_source;
	int retry;
};

struct mapper_async_subtree
{
	char *namespace;
	char *interface;
	void (*callback)(int, void *);
	void *userdata;
	sd_event *loop;
	sd_bus *conn;
	sd_bus_slot *slot;
	sd_event_source *event_source;
	int finished;
	int op;
	int retry;
};

static int async_wait_match_introspection_complete(sd_bus_message *, void *,
		sd_bus_error *);
static int async_wait_check_done(mapper_async_wait *);
static void async_wait_done(int r, mapper_async_wait *);
static int async_wait_get_objects(mapper_async_wait *);
static int async_wait_getobject_callback(sd_bus_message *,
		void *, sd_bus_error *);

static int async_subtree_match_callback(sd_bus_message *, void *,
		sd_bus_error *);
static void async_subtree_done(int r, mapper_async_subtree *);
static int async_subtree_getpaths(mapper_async_subtree *);
static int async_subtree_getpaths_callback(sd_bus_message *,
		void *, sd_bus_error *);

static int sarraylen(char *array[])
{
	int count = 0;
	char **p = array;

	while(*p != NULL) {
		++count;
		++p;
	}

	return count;
}

static void sarrayfree(char *array[])
{
	char **p = array;
	while(*p != NULL) {
		free(*p);
		++p;
	}
	free(array);
}

static char **sarraydup(char *array[])
{
	int count = sarraylen(array);
	int i;
	char **ret = NULL;

	ret = malloc(sizeof(*ret) * count);
	if(!ret)
		return NULL;

	for(i=0; i<count; ++i) {
		ret[i] = strdup(array[i]);
		if(!ret[i])
			goto error;
	}

	return ret;

error:
	sarrayfree(ret);
	return NULL;
}

static int async_wait_timeout_callback(sd_event_source *s,
		uint64_t usec, void *userdata)
{
	int r;
	struct async_wait_callback_data *data = userdata;
	mapper_async_wait *wait = data->wait;

	sd_event_source_unref(data->event_source);
	r = sd_bus_call_method_async(
			wait->conn,
			NULL,
			MAPPER_BUSNAME,
			MAPPER_PATH,
			MAPPER_INTERFACE,
			"GetObject",
			async_wait_getobject_callback,
			data,
			"sas",
			data->path,
			0,
			NULL);
	if(r < 0) {
		async_wait_done(r, wait);
		free(data);
	}

	return 0;
}

static int async_wait_getobject_callback(sd_bus_message *m,
		void *userdata,
		sd_bus_error *e)
{
	int i, r;
	struct async_wait_callback_data *data = userdata;
	mapper_async_wait *wait = data->wait;
	uint64_t now;

	if(wait->finished)
		goto exit;

	r = sd_bus_message_get_errno(m);
	if(r == ENOENT)
		goto exit;

	if(r == EBUSY && data->retry < mapper_busy_retries) {
		r = sd_event_now(wait->loop,
				CLOCK_MONOTONIC,
				&now);
		if(r < 0) {
			async_wait_done(r, wait);
			goto exit;
		}

		++data->retry;
		r = sd_event_add_time(wait->loop,
				&data->event_source,
				CLOCK_MONOTONIC,
				now + mapper_busy_delay_interval_usec,
				0,
				async_wait_timeout_callback,
				data);
		if(r < 0) {
			async_wait_done(r, wait);
			goto exit;
		}

		return 0;
	}

	if(r) {
		async_wait_done(-r, wait);
		goto exit;
	}

	for(i=0; i<wait->count; ++i) {
		if(!strcmp(data->path, wait->objs[i])) {
			wait->status[i] = 1;
		}
	}

	if(async_wait_check_done(wait))
		async_wait_done(0, wait);

exit:
	free(data);
	return 0;
}

static int async_wait_get_objects(mapper_async_wait *wait)
{
	int i, r;
	struct async_wait_callback_data *data = NULL;

	for(i=0; i<wait->count; ++i) {
		if(wait->status[i])
			continue;
		data = malloc(sizeof(*data));
		data->wait = wait;
		data->path = wait->objs[i];
		data->retry = 0;
		data->event_source = NULL;
		r = sd_bus_call_method_async(
				wait->conn,
				NULL,
				MAPPER_BUSNAME,
				MAPPER_PATH,
				MAPPER_INTERFACE,
				"GetObject",
				async_wait_getobject_callback,
				data,
				"sas",
				wait->objs[i],
				0,
				NULL);
		if(r < 0) {
			free(data);
			fprintf(stderr, "Error invoking method: %s\n",
					strerror(-r));
			return r;
		}
	}

	return 0;
}

static int async_wait_match_introspection_complete(sd_bus_message *m, void *w,
		sd_bus_error *e)
{
	int r;

	mapper_async_wait *wait = w;
	if(wait->finished)
		return 0;

	r = async_wait_get_objects(wait);
	if(r < 0)
		async_wait_done(r, wait);

	return 0;
}

static void async_wait_done(int r, mapper_async_wait *w)
{
	if(w->finished)
		return;

	w->finished = 1;
	sd_bus_slot_unref(w->introspection_slot);
	sd_bus_slot_unref(w->intf_slot);

	if(w->callback)
		w->callback(r, w->userdata);
}

static int async_wait_check_done(mapper_async_wait *w)
{
	int i;

	if(w->finished)
		return 1;

	for(i=0; i<w->count; ++i)
		if(!w->status[i])
			return 0;

	return 1;
}

void mapper_wait_async_free(mapper_async_wait *w)
{
	free(w->status);
	sarrayfree(w->objs);
	free(w);
}

int mapper_wait_async(sd_bus *conn,
		sd_event *loop,
		char *objs[],
		void (*callback)(int, void *),
		void *userdata,
		mapper_async_wait **w)
{
	int r;
	mapper_async_wait *wait = NULL;

	wait = malloc(sizeof(*wait));
	if(!wait)
		return -ENOMEM;

	memset(wait, 0, sizeof(*wait));
	wait->conn = conn;
	wait->loop = loop;
	wait->callback = callback;
	wait->userdata = userdata;
	wait->count = sarraylen(objs);
	if(!wait->count)
		return 0;

	wait->objs = sarraydup(objs);
	if(!wait->objs) {
		r = -ENOMEM;
		goto free_wait;
	}

	wait->status = malloc(sizeof(*wait->status) * wait->count);
	if(!wait->status) {
		r = -ENOMEM;
		goto free_objs;
	}
	memset(wait->status, 0, sizeof(*wait->status) * wait->count);

	r = sd_bus_add_match(conn,
			&wait->introspection_slot,
			async_wait_introspection_match,
			async_wait_match_introspection_complete,
			wait);
	if(r < 0) {
		fprintf(stderr, "Error adding match rule: %s\n",
				strerror(-r));
		goto free_status;
	}

	r = sd_bus_add_match(conn,
                        &wait->intf_slot,
			async_wait_interfaces_added_match,
                        async_wait_match_introspection_complete,
                        wait);
	if(r < 0) {
		fprintf(stderr, "Error adding match rule: %s\n",
				strerror(-r));
		goto unref_name_slot;
	}

	r = async_wait_get_objects(wait);
	if(r < 0) {
		fprintf(stderr, "Error calling method: %s\n",
				strerror(-r));
		goto unref_intf_slot;
	}

	*w = wait;

	return 0;

unref_intf_slot:
	sd_bus_slot_unref(wait->intf_slot);
unref_name_slot:
	sd_bus_slot_unref(wait->introspection_slot);
free_status:
	free(wait->status);
free_objs:
	sarrayfree(wait->objs);
free_wait:
	free(wait);

	return r;
}

static int async_subtree_timeout_callback(sd_event_source *s,
		uint64_t usec, void *userdata)
{
	int r;
	struct mapper_async_subtree *subtree = userdata;

	sd_event_source_unref(subtree->event_source);
	r = sd_bus_call_method_async(
			subtree->conn,
			NULL,
			MAPPER_BUSNAME,
			MAPPER_PATH,
			MAPPER_INTERFACE,
			"GetSubTreePaths",
			async_subtree_getpaths_callback,
			subtree,
			"sias",
			subtree->namespace,
			0, 1,
			subtree->interface);
	if(r < 0)
		async_subtree_done(r, subtree);

	return 0;
}

static int async_subtree_getpaths_callback(sd_bus_message *m,
		void *userdata,
		sd_bus_error *e)
{
	int r;
	char *intf = NULL;
	struct mapper_async_subtree *subtree = userdata;
	uint64_t now;

	if(subtree->finished)
		goto exit;

	r = sd_bus_message_get_errno(m);

	if(r == ENOENT) {
		if (subtree->op == MAPPER_OP_REMOVE)
			r = 0;
		else
			goto exit;
	}

	if(r == EBUSY && subtree->retry < mapper_busy_retries) {
		r = sd_event_now(subtree->loop,
				CLOCK_MONOTONIC,
				&now);
		if(r < 0) {
			async_subtree_done(r, subtree);
			goto exit;
		}

		++subtree->retry;
		r = sd_event_add_time(subtree->loop,
				&subtree->event_source,
				CLOCK_MONOTONIC,
				now + mapper_busy_delay_interval_usec,
				0,
				async_subtree_timeout_callback,
				subtree);
		if(r < 0) {
			async_subtree_done(r, subtree);
			goto exit;
		}

		return 0;
	}

	if(r) {
		async_subtree_done(-r, subtree);
		goto exit;
	}

	sd_bus_message_read(m, "as", 1, &intf);
	if (subtree->op == MAPPER_OP_REMOVE) {
		/* For remove, operation is complete when the interface is not present */
		if (intf == NULL)
			async_subtree_done(0, subtree);
	}

exit:
	return 0;
}

static int async_subtree_getpaths(mapper_async_subtree *subtree)
{
	int r = 0;

	subtree->retry = 0;
	subtree->event_source = NULL;
	r = sd_bus_call_method_async(
			subtree->conn,
			NULL,
			MAPPER_BUSNAME,
			MAPPER_PATH,
			MAPPER_INTERFACE,
			"GetSubTreePaths",
			async_subtree_getpaths_callback,
			subtree,
			"sias",
			subtree->namespace,
			0, 1,
			subtree->interface);
	if (r < 0) {
		fprintf(stderr, "Error invoking method: %s\n", strerror(-r));
		return r;
	}

	return 0;
}

static int async_subtree_match_callback(sd_bus_message *m,
		void *t,
		sd_bus_error *e)
{
	int r;

	mapper_async_subtree *subtree = t;
	if(subtree->finished)
		return 0;

	r = async_subtree_getpaths(subtree);
	if(r < 0)
		async_subtree_done(r, subtree);

	return 0;
}

static void async_subtree_done(int r, mapper_async_subtree *t)
{
	if(t->finished)
		return;

	t->finished = 1;
	sd_bus_slot_unref(t->slot);

	if(t->callback)
		t->callback(r, t->userdata);
}

int mapper_subtree_async(sd_bus *conn,
		sd_event *loop,
		char *namespace,
		char *interface,
		void (*callback)(int, void *),
		void *userdata,
		mapper_async_subtree **t,
		int op)
{
	int r = 0;
	mapper_async_subtree *subtree = NULL;

	subtree = malloc(sizeof(*subtree));
	if(!subtree)
		return -ENOMEM;

	memset(subtree, 0, sizeof(*subtree));
	subtree->conn = conn;
	subtree->loop = loop;
	subtree->namespace = namespace;
	subtree->interface = interface;
	subtree->callback = callback;
	subtree->userdata = userdata;
	subtree->op = op;

	if (subtree->op == MAPPER_OP_REMOVE) {
		r = sd_bus_add_match(
				conn,
				&subtree->slot,
				interfaces_removed_match,
				async_subtree_match_callback,
				subtree);
		if(r < 0) {
			fprintf(stderr, "Error adding match rule: %s\n",
					strerror(-r));
			goto unref_slot;
		}
	} else {
		/* Operation not supported */
		r = -EINVAL;
		goto free_subtree;
	}

	r = async_subtree_getpaths(subtree);
	if(r < 0) {
		fprintf(stderr, "Error calling method: %s\n",
				strerror(-r));
		goto unref_slot;
	}

	*t = subtree;

	return 0;

unref_slot:
	sd_bus_slot_unref(subtree->slot);
free_subtree:
	free(subtree);

	return r;
}

int mapper_get_object(sd_bus *conn, const char *obj, sd_bus_message **reply)
{
	sd_bus_error error = SD_BUS_ERROR_NULL;
	sd_bus_message *request = NULL;
	int r, retry = 0;

	r = sd_bus_message_new_method_call(
			conn,
			&request,
			MAPPER_BUSNAME,
			MAPPER_PATH,
			MAPPER_INTERFACE,
			"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(retry < mapper_busy_retries) {
		sd_bus_error_free(&error);
		r = sd_bus_call(conn, request, 0, &error, reply);
		if (r < 0 && sd_bus_error_get_errno(&error) == EBUSY) {
			++retry;

			if(retry != mapper_busy_retries)
				usleep(mapper_busy_delay_interval_usec);
			continue;
		}
		break;
	}

	if (r < 0)
		goto exit;

exit:
	sd_bus_error_free(&error);
	sd_bus_message_unref(request);

	return r;
}

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

	r = mapper_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;
}
