/**
 * 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 "mapper.h"

#include <errno.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/timerfd.h>
#include <systemd/sd-bus.h>
#include <systemd/sd-event.h>
#include <unistd.h>

#include "internal.h"

#define _public_ __attribute__((__visibility__("default")))
#define _unused_ __attribute__((unused))

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;
    size_t 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*);

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

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

    return count;
}

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

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

    ret = calloc(count + 1, sizeof(*ret));
    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(_unused_ sd_event_source* s,
                                       _unused_ 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,
                                         _unused_ sd_bus_error* e)
{
    size_t i;
    int r;
    struct async_wait_callback_data* data = userdata;
    mapper_async_wait* wait = data->wait;
    uint64_t next_retry;

    if (wait->finished)
        goto exit;

    if (sd_bus_message_is_method_error(
            m, "xyz.openbmc_project.Common.Error.ResourceNotFound"))
        goto exit;

    r = sd_bus_message_get_errno(m);

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

        next_retry += mapper_busy_delay_interval_usec * (1 << data->retry);
        r = sd_event_add_time(wait->loop, &data->event_source, CLOCK_MONOTONIC,
                              next_retry, 0, async_wait_timeout_callback, data);
        ++data->retry;
        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)
{
    size_t i;
    int 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(_unused_ sd_bus_message* m,
                                                   void* w,
                                                   _unused_ 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)
{
    size_t i;

    if (w->finished)
        return 1;

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

    return 1;
}

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

_public_ 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)
    {
        r = 0;
        goto free_wait;
    }

    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(_unused_ sd_event_source* s,
                                          _unused_ 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,
                                           _unused_ sd_bus_error* e)
{
    int r;
    struct mapper_async_subtree* subtree = userdata;
    uint64_t next_retry;

    if (subtree->finished)
        goto exit;

    r = sd_bus_message_get_errno(m);

    if (sd_bus_message_is_method_error(
            m, "xyz.openbmc_project.Common.Error.ResourceNotFound"))
    {
        if (subtree->op == MAPPER_OP_REMOVE)
            r = 0;
        else
            goto exit;
    }

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

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

        return 0;
    }

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

    if (subtree->op == MAPPER_OP_REMOVE)
    {
        r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "s");
        if (r < 0)
        {
            async_subtree_done(r, subtree);
            goto exit;
        }

        r = sd_bus_message_at_end(m, false);
        if (r < 0)
        {
            async_subtree_done(r, subtree);
            goto exit;
        }

        /* For remove, operation is complete when the interface is not present
         * we know it is empty if the returned array is empty
         */
        if (r)
            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(_unused_ sd_bus_message* m, void* t,
                                        _unused_ 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);
}

_public_ 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;
}

_public_ int mapper_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, 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 (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;
}

_public_ 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;
}
