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

#include "internal.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>

#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, "xyz.openbmc_project.ObjectMapper",
        "/xyz/openbmc_project/object_mapper",
        "xyz.openbmc_project.ObjectMapper", "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, "xyz.openbmc_project.ObjectMapper",
            "/xyz/openbmc_project/object_mapper",
            "xyz.openbmc_project.ObjectMapper", "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, "xyz.openbmc_project.ObjectMapper",
        "/xyz/openbmc_project/object_mapper",
        "xyz.openbmc_project.ObjectMapper", "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, "xyz.openbmc_project.ObjectMapper",
        "/xyz/openbmc_project/object_mapper",
        "xyz.openbmc_project.ObjectMapper", "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, "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;
}

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