/***
  This file is part of avahi.

  avahi is free software; you can redistribute it and/or modify it
  under the terms of the GNU Lesser General Public License as
  published by the Free Software Foundation; either version 2.1 of the
  License, or (at your option) any later version.

  avahi is distributed in the hope that it will be useful, but WITHOUT
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
  Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with avahi; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  USA.
***/

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <assert.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>

#include <avahi-common/error.h>
#include <avahi-common/dbus.h>
#include "avahi-common/avahi-malloc.h"
#include <avahi-core/log.h>
#include <avahi-core/core.h>

#ifdef ENABLE_CHROOT
#include "chroot.h"
#endif

#include "main.h"
#include "dbus-util.h"

DBusHandlerResult avahi_dbus_respond_error(DBusConnection *c, DBusMessage *m, int error, const char *text) {
    DBusMessage *reply;

    assert(-error > -AVAHI_OK);
    assert(-error < -AVAHI_ERR_MAX);

    if (!text)
        text = avahi_strerror(error);

    reply = dbus_message_new_error(m, avahi_error_number_to_dbus(error), text);

    if (!reply) {
        avahi_log_error("Failed allocate message");
        return DBUS_HANDLER_RESULT_NEED_MEMORY;
    }

    dbus_connection_send(c, reply, NULL);
    dbus_message_unref(reply);

    avahi_log_debug(__FILE__": Responding error '%s' (%i)", text, error);

    return DBUS_HANDLER_RESULT_HANDLED;
}

DBusHandlerResult avahi_dbus_respond_string(DBusConnection *c, DBusMessage *m, const char *text) {
    DBusMessage *reply;

    reply = dbus_message_new_method_return(m);

    if (!reply) {
        avahi_log_error("Failed allocate message");
        return DBUS_HANDLER_RESULT_NEED_MEMORY;
    }

    dbus_message_append_args(reply, DBUS_TYPE_STRING, &text, DBUS_TYPE_INVALID);
    dbus_connection_send(c, reply, NULL);
    dbus_message_unref(reply);

    return DBUS_HANDLER_RESULT_HANDLED;
}

DBusHandlerResult avahi_dbus_respond_int32(DBusConnection *c, DBusMessage *m, int32_t i) {
    DBusMessage *reply;

    reply = dbus_message_new_method_return(m);

    if (!reply) {
        avahi_log_error("Failed allocate message");
        return DBUS_HANDLER_RESULT_NEED_MEMORY;
    }

    dbus_message_append_args(reply, DBUS_TYPE_INT32, &i, DBUS_TYPE_INVALID);
    dbus_connection_send(c, reply, NULL);
    dbus_message_unref(reply);

    return DBUS_HANDLER_RESULT_HANDLED;
}

DBusHandlerResult avahi_dbus_respond_uint32(DBusConnection *c, DBusMessage *m, uint32_t u) {
    DBusMessage *reply;

    reply = dbus_message_new_method_return(m);

    if (!reply) {
        avahi_log_error("Failed allocate message");
        return DBUS_HANDLER_RESULT_NEED_MEMORY;
    }

    dbus_message_append_args(reply, DBUS_TYPE_UINT32, &u, DBUS_TYPE_INVALID);
    dbus_connection_send(c, reply, NULL);
    dbus_message_unref(reply);

    return DBUS_HANDLER_RESULT_HANDLED;
}

DBusHandlerResult avahi_dbus_respond_boolean(DBusConnection *c, DBusMessage *m, int b) {
    DBusMessage *reply;

    reply = dbus_message_new_method_return(m);

    if (!reply) {
        avahi_log_error("Failed allocate message");
        return DBUS_HANDLER_RESULT_NEED_MEMORY;
    }

    dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &b, DBUS_TYPE_INVALID);
    dbus_connection_send(c, reply, NULL);
    dbus_message_unref(reply);

    return DBUS_HANDLER_RESULT_HANDLED;
}

DBusHandlerResult avahi_dbus_respond_ok(DBusConnection *c, DBusMessage *m) {
    DBusMessage *reply;

    reply = dbus_message_new_method_return(m);

    if (!reply) {
        avahi_log_error("Failed allocate message");
        return DBUS_HANDLER_RESULT_NEED_MEMORY;
    }

    dbus_connection_send(c, reply, NULL);
    dbus_message_unref(reply);

    return DBUS_HANDLER_RESULT_HANDLED;
}

DBusHandlerResult avahi_dbus_respond_path(DBusConnection *c, DBusMessage *m, const char *path) {
    DBusMessage *reply;

    reply = dbus_message_new_method_return(m);

    if (!reply) {
        avahi_log_error("Failed allocate message");
        return DBUS_HANDLER_RESULT_NEED_MEMORY;
    }

    dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID);
    dbus_connection_send(c, reply, NULL);
    dbus_message_unref(reply);

    return DBUS_HANDLER_RESULT_HANDLED;
}

void avahi_dbus_append_server_error(DBusMessage *reply) {
    const char *t;

    t = avahi_error_number_to_dbus(avahi_server_errno(avahi_server));

    dbus_message_append_args(
        reply,
        DBUS_TYPE_STRING, &t,
        DBUS_TYPE_INVALID);
}

const char *avahi_dbus_map_browse_signal_name(AvahiBrowserEvent e) {
    switch (e) {
        case AVAHI_BROWSER_NEW : return "ItemNew";
        case AVAHI_BROWSER_REMOVE : return "ItemRemove";
        case AVAHI_BROWSER_FAILURE : return "Failure";
        case AVAHI_BROWSER_CACHE_EXHAUSTED : return "CacheExhausted";
        case AVAHI_BROWSER_ALL_FOR_NOW : return "AllForNow";
    }

    abort();
}

const char *avahi_dbus_map_resolve_signal_name(AvahiResolverEvent e) {
    switch (e) {
        case AVAHI_RESOLVER_FOUND : return "Found";
        case AVAHI_RESOLVER_FAILURE : return "Failure";
    }

    abort();
}

static char *file_get_contents(const char *fname) {
    int fd = -1;
    struct stat st;
    ssize_t size;
    char *buf = NULL;

    assert(fname);

#ifdef ENABLE_CHROOT
    fd = avahi_chroot_helper_get_fd(fname);
#else
    fd = open(fname, O_RDONLY);
#endif

    if (fd < 0) {
        avahi_log_error("Failed to open %s: %s", fname, strerror(errno));
        goto fail;
    }

    if (fstat(fd, &st) < 0) {
        avahi_log_error("stat(%s) failed: %s", fname, strerror(errno));
        goto fail;
    }

    if (!(S_ISREG(st.st_mode))) {
        avahi_log_error("Invalid file %s", fname);
        goto fail;
    }

    if (st.st_size > 1024*1024) { /** 1MB */
        avahi_log_error("File too large %s", fname);
        goto fail;
    }

    buf = avahi_new(char, st.st_size+1);

    if ((size = read(fd, buf, st.st_size)) < 0) {
        avahi_log_error("read() failed: %s\n", strerror(errno));
        goto fail;
    }

    buf[size] = 0;

    close(fd);

    return buf;

fail:
    if (fd >= 0)
        close(fd);

    if (buf)
        avahi_free(buf);

    return NULL;

}

DBusHandlerResult avahi_dbus_handle_introspect(DBusConnection *c, DBusMessage *m, const char *fname) {
#ifdef AVAHI_DBUS_INTROSPECTION_DIR
    char *contents, *path;
    DBusError error;

    assert(c);
    assert(m);
    assert(fname);

    dbus_error_init(&error);

    if (!dbus_message_get_args(m, &error, DBUS_TYPE_INVALID)) {
        avahi_log_error("Error parsing Introspect message: %s", error.message);
        goto fail;
    }

    path = avahi_strdup_printf("%s/%s", AVAHI_DBUS_INTROSPECTION_DIR, fname);
    contents = file_get_contents(path);
    avahi_free(path);

    if (!contents) {
        avahi_log_error("Failed to load introspection data.");
        goto fail;
    }

    avahi_dbus_respond_string(c, m, contents);
    avahi_free(contents);

    return DBUS_HANDLER_RESULT_HANDLED;

fail:
    if (dbus_error_is_set(&error))
        dbus_error_free(&error);
#endif

    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;

}

void avahi_dbus_append_string_list(DBusMessage *reply, AvahiStringList *txt) {
    AvahiStringList *p;
    DBusMessageIter iter, sub;

    assert(reply);

    dbus_message_iter_init_append(reply, &iter);
    dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "ay", &sub);

    for (p = txt; p; p = p->next) {
        DBusMessageIter sub2;
        const uint8_t *data = p->text;

        dbus_message_iter_open_container(&sub, DBUS_TYPE_ARRAY, "y", &sub2);
        dbus_message_iter_append_fixed_array(&sub2, DBUS_TYPE_BYTE, &data, p->size);
        dbus_message_iter_close_container(&sub, &sub2);

    }
    dbus_message_iter_close_container(&iter, &sub);
}

int avahi_dbus_read_rdata(DBusMessage *m, int idx, void **rdata, uint32_t *size) {
    DBusMessageIter iter, sub;
    int n, j;
    uint8_t *k;

    assert(m);

    dbus_message_iter_init(m, &iter);

    for (j = 0; j < idx; j++)
       dbus_message_iter_next(&iter);

    if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
        dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_BYTE)
        goto fail;

    dbus_message_iter_recurse(&iter, &sub);
    dbus_message_iter_get_fixed_array(&sub, &k, &n);

    *rdata = k;
    *size = n;

    return 0;

fail:
    avahi_log_warn("Error parsing data");

    *rdata = NULL;
    size = 0;
    return -1;
}

int avahi_dbus_read_strlst(DBusMessage *m, int idx, AvahiStringList **l) {
    DBusMessageIter iter, sub;
    int j;
    AvahiStringList *strlst = NULL;

    assert(m);
    assert(l);

    dbus_message_iter_init(m, &iter);

    for (j = 0; j < idx; j++)
        dbus_message_iter_next(&iter);

    if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
        dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_ARRAY)
        goto fail;

    dbus_message_iter_recurse(&iter, &sub);

    for (;;) {
        int at, n;
        const uint8_t *k;
        DBusMessageIter sub2;

        if ((at = dbus_message_iter_get_arg_type(&sub)) == DBUS_TYPE_INVALID)
            break;

        assert(at == DBUS_TYPE_ARRAY);

        if (dbus_message_iter_get_element_type(&sub) != DBUS_TYPE_BYTE)
            goto fail;

        dbus_message_iter_recurse(&sub, &sub2);

        k = (const uint8_t*) "";
        n = 0;
        dbus_message_iter_get_fixed_array(&sub2, &k, &n);

        if (!k)
            k = (const uint8_t*) "";

        strlst = avahi_string_list_add_arbitrary(strlst, k, n);

        dbus_message_iter_next(&sub);
    }

    *l = strlst;

    return 0;

fail:
    avahi_log_warn("Error parsing TXT data");

    avahi_string_list_free(strlst);
    *l = NULL;
    return -1;
}

int avahi_dbus_is_our_own_service(Client *c, AvahiIfIndex interface, AvahiProtocol protocol, const char *name, const char *type, const char *domain) {
    AvahiSEntryGroup *g;

    if (avahi_server_get_group_of_service(avahi_server, interface, protocol, name, type, domain, &g) == AVAHI_OK) {
        EntryGroupInfo *egi;

        for (egi = c->entry_groups; egi; egi = egi->entry_groups_next)
            if (egi->entry_group == g)
                return 1;
    }

    return 0;
}

int avahi_dbus_append_rdata(DBusMessage *message, const void *rdata, size_t size) {
    DBusMessageIter iter, sub;

    assert(message);

    dbus_message_iter_init_append(message, &iter);

    if (!(dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE_AS_STRING, &sub)) ||
        !(dbus_message_iter_append_fixed_array(&sub, DBUS_TYPE_BYTE, &rdata, size)) ||
        !(dbus_message_iter_close_container(&iter, &sub)))
        return -1;

    return 0;
}
