/* dnsmasq is Copyright (c) 2000-2018 Simon Kelley

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; version 2 dated June, 1991, or
   (at your option) version 3 dated 29 June, 2007.
 
   This program 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 General Public License for more details.
     
   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "dnsmasq.h"

#ifdef HAVE_UBUS

#include <libubus.h>

static struct blob_buf b;
static int notify;
static int error_logged = 0;

static int ubus_handle_metrics(struct ubus_context *ctx, struct ubus_object *obj,
			       struct ubus_request_data *req, const char *method,
			       struct blob_attr *msg);

static void ubus_subscribe_cb(struct ubus_context *ctx, struct ubus_object *obj);

static const struct ubus_method ubus_object_methods[] = {
  UBUS_METHOD_NOARG("metrics", ubus_handle_metrics),
};

static struct ubus_object_type ubus_object_type =
  UBUS_OBJECT_TYPE("dnsmasq", ubus_object_methods);

static struct ubus_object ubus_object = {
  .name = "dnsmasq",
  .type = &ubus_object_type,
  .methods = ubus_object_methods,
  .n_methods = ARRAY_SIZE(ubus_object_methods),
  .subscribe_cb = ubus_subscribe_cb,
};

static void ubus_subscribe_cb(struct ubus_context *ctx, struct ubus_object *obj)
{
  (void)ctx;

  my_syslog(LOG_DEBUG, _("UBus subscription callback: %s subscriber(s)"), obj->has_subscribers ? "1" : "0");
  notify = obj->has_subscribers;
}

static void ubus_destroy(struct ubus_context *ubus)
{
  // Forces re-initialization when we're reusing the same definitions later on.
  ubus_object.id = 0;
  ubus_object_type.id = 0;

  ubus_free(ubus);
  daemon->ubus = NULL;
}

static void ubus_disconnect_cb(struct ubus_context *ubus)
{
  int ret;

  ret = ubus_reconnect(ubus, NULL);
  if (ret)
    {
      my_syslog(LOG_ERR, _("Cannot reconnect to UBus: %s"), ubus_strerror(ret));

      ubus_destroy(ubus);
    }
}

void ubus_init()
{
  struct ubus_context *ubus = NULL;
  int ret = 0;

  ubus = ubus_connect(NULL);
  if (!ubus)
    {
      if (!error_logged)
        {
          my_syslog(LOG_ERR, _("Cannot initialize UBus: connection failed"));
          error_logged = 1;
        }

      ubus_destroy(ubus);
      return;
    }

  ret = ubus_add_object(ubus, &ubus_object);
  if (ret)
    {
      if (!error_logged)
        {
          my_syslog(LOG_ERR, _("Cannot add object to UBus: %s"), ubus_strerror(ret));
          error_logged = 1;
        }
      return;
    }

  ubus->connection_lost = ubus_disconnect_cb;
  daemon->ubus = ubus;
  error_logged = 0;

  my_syslog(LOG_INFO, _("Connected to system UBus"));
}

void set_ubus_listeners()
{
  struct ubus_context *ubus = (struct ubus_context *)daemon->ubus;
  if (!ubus)
    {
      if (!error_logged)
        {
          my_syslog(LOG_ERR, _("Cannot set UBus listeners: no connection"));
          error_logged = 1;
        }
      return;
    }

  error_logged = 0;

  poll_listen(ubus->sock.fd, POLLIN);
  poll_listen(ubus->sock.fd, POLLERR);
  poll_listen(ubus->sock.fd, POLLHUP);
}

void check_ubus_listeners()
{
  struct ubus_context *ubus = (struct ubus_context *)daemon->ubus;
  if (!ubus)
    {
      if (!error_logged)
        {
          my_syslog(LOG_ERR, _("Cannot poll UBus listeners: no connection"));
          error_logged = 1;
        }
      return;
    }
  
  error_logged = 0;

  if (poll_check(ubus->sock.fd, POLLIN))
    ubus_handle_event(ubus);
  
  if (poll_check(ubus->sock.fd, POLLHUP | POLLERR))
    {
      my_syslog(LOG_INFO, _("Disconnecting from UBus"));

      ubus_destroy(ubus);
    }
}

static int ubus_handle_metrics(struct ubus_context *ctx, struct ubus_object *obj,
			       struct ubus_request_data *req, const char *method,
			       struct blob_attr *msg)
{
  int i;

  (void)obj;
  (void)method;
  (void)msg;

  blob_buf_init(&b, BLOBMSG_TYPE_TABLE);

  for (i=0; i < __METRIC_MAX; i++)
    blobmsg_add_u32(&b, get_metric_name(i), daemon->metrics[i]);
  
  return ubus_send_reply(ctx, req, b.head);
}

void ubus_event_bcast(const char *type, const char *mac, const char *ip, const char *name, const char *interface)
{
  struct ubus_context *ubus = (struct ubus_context *)daemon->ubus;
  int ret;

  if (!ubus || !notify)
    return;

  blob_buf_init(&b, BLOBMSG_TYPE_TABLE);
  if (mac)
    blobmsg_add_string(&b, "mac", mac);
  if (ip)
    blobmsg_add_string(&b, "ip", ip);
  if (name)
    blobmsg_add_string(&b, "name", name);
  if (interface)
    blobmsg_add_string(&b, "interface", interface);
  
  ret = ubus_notify(ubus, &ubus_object, type, b.head, -1);
  if (!ret)
    my_syslog(LOG_ERR, _("Failed to send UBus event: %s"), ubus_strerror(ret));
}


#endif /* HAVE_UBUS */
