/*
 *
 *  Visual Voicemail Daemon
 *
 *  Copyright (C) 2010-2011, Intel Corporation
 *                2021, Chris Talbot <chris@talbothome.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 as
 *  published by the Free Software Foundation.
 *
 *  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, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

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

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <gio/gio.h>

#include "version.h"
#include "vvm.h"
#include "dbus.h"

static GMainLoop *main_loop = NULL;

static volatile sig_atomic_t __terminated = 0;

static void
sig_term (int sig)
{
  if (__terminated > 0)
    return;

  __terminated = 1;

  g_message ("Terminating");

  g_main_loop_quit (main_loop);
}

static gboolean option_version = FALSE;
static gboolean global_debug = FALSE;

static GOptionEntry options[] = {
  { "debug", 'd', 0, G_OPTION_ARG_NONE, &global_debug,
    "Enable debugging output" },
  { "version", 'v', 0, G_OPTION_ARG_NONE, &option_version,
    "Show version information and exit" },
  { NULL },
};

static void
on_bus_acquired (GDBusConnection *connection,
                 const gchar     *name,
                 gpointer         user_data)
{
  DBG ("Dbus Bus acquired!");

  __vvm_dbus_set_connection (connection);

  __vvm_service_init (global_debug);

  __vvm_plugin_init ();
}

static void
on_name_acquired (GDBusConnection *connection,
                  const gchar     *name,
                  gpointer         user_data)
{
  DBG ("Dbus name acquired!");
}

static void
on_name_lost (GDBusConnection *connection,
              const gchar     *name,
              gpointer         user_data)
{
  g_warning ("Lost Dbus Connection! Exiting....");
  exit (1);
}

int
main (int   argc,
      char *argv[])
{
  GOptionContext *context;
  GError *error = NULL;
  struct sigaction sa;
  guint owner_id;
  g_autofree char *vvm_home_path = NULL;


  context = g_option_context_new (NULL);
  g_option_context_add_main_entries (context, options, NULL);

  if (g_option_context_parse (context, &argc, &argv, &error) == FALSE)
    {
      if (error != NULL)
        {
          g_printerr ("%s\n", error->message);
          g_error_free (error);
        }
      else
        g_printerr ("An unknown error occurred\n");
      exit (1);
    }

  /* Check if the home/.vvm directory can be written to */
  vvm_home_path  = g_build_filename (g_get_home_dir () , ".vvm", NULL);
  if (g_mkdir_with_parents (vvm_home_path, 0700) != 0)
    g_printerr ("Cannot create directory in '%s'\n", vvm_home_path);
  if (access (vvm_home_path, R_OK | W_OK) != 0)
    {
      g_printerr ("Cannot read and write in '%s', exiting...\n", vvm_home_path);
      exit (1);
    }

  g_option_context_free (context);

  if (option_version == TRUE)
    {
      printf ("%s, git version: %s\n", VERSION, PACKAGE_VCS_VERSION);
      exit (0);
    }

  if (global_debug == TRUE)
    g_setenv ("G_MESSAGES_DEBUG", "all", TRUE);

  main_loop = g_main_loop_new (NULL, FALSE);

  __vvm_dbus_set_introspection_data ();

  owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
                             VVM_SERVICE,
                             G_BUS_NAME_OWNER_FLAGS_NONE,
                             on_bus_acquired,
                             on_name_acquired,
                             on_name_lost,
                             NULL,
                             NULL);

  g_message ("VVMD version %s, git version: %s", VERSION, PACKAGE_VCS_VERSION);

  memset (&sa, 0, sizeof(sa));
  sa.sa_handler = sig_term;
  sigaction (SIGINT, &sa, NULL);
  sigaction (SIGTERM, &sa, NULL);

  g_main_loop_run (main_loop);

  __vvm_plugin_cleanup ();

  __vvm_service_cleanup ();

  g_message ("EXIT");

  g_bus_unown_name (owner_id);

  __vvm_dbus_unref_introspection_data ();

  g_main_loop_unref (main_loop);

  return 0;
}
