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

#include "mapper.h"

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;
    size_t attempts = 0;
    const size_t max_attempts = 4;

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

    /* Mapper waits are typically run early in the boot process, and in some
     * cases the CPU and/or object manager daemon are so busy that the
     * GetObject call may fail with a timeout and cause the event loop to exit.
     * If this happens, retry a few times.  Don't retry on other failures.
     */
    while (1)
    {
        attempts++;

        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, "Event loop exited: %s\n", strerror(-r));

            if (-r == ETIMEDOUT)
            {
                if (attempts <= max_attempts)
                {
                    fprintf(stderr, "Retrying in 5s\n");
                    sleep(5);
                    sd_event_unref(loop);
                    sd_bus_unref(conn);
                    continue;
                }
                else
                {
                    fprintf(stderr, "Giving up\n");
                }
            }
            else
            {
                goto finish;
            }
        }

        break;
    }

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)
    {
        /* If this function has been called after the interface in   */
        /* question has already been removed, then GetSubTree will   */
        /* fail and it will show up here.  Treat as success instead. */
        if (r == -ENXIO)
        {
            r = 0;
        }
        else
        {
            fprintf(stderr, "Error starting event loop: %d(%s)\n", r,
                    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"
        "  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], "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);
}
