/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * 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; either version 2 of the License, or
 * (at your option) any later version.
 *
 * 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:
 *
 * Copyright (C) 2008 - 2009 Novell, Inc.
 * Copyright (C) 2009 - 2011 Red Hat, Inc.
 */

#include <config.h>
#include <signal.h>
#include <syslog.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>

#include <gio/gio.h>
#include <glib-unix.h>

#include "ModemManager.h"

#include "mm-base-manager.h"
#include "mm-log.h"
#include "mm-context.h"

#if WITH_SUSPEND_RESUME
# include "mm-sleep-monitor.h"
#endif

/* Maximum time to wait for all modems to get disabled and removed */
#define MAX_SHUTDOWN_TIME_SECS 20

static GMainLoop *loop;
static MMBaseManager *manager;

static gboolean
quit_cb (gpointer user_data)
{
    mm_info ("Caught signal, shutting down...");

    if (manager)
        g_object_set (manager, MM_BASE_MANAGER_CONNECTION, NULL, NULL);

    if (loop)
        g_idle_add ((GSourceFunc) g_main_loop_quit, loop);
    else
        exit (0);
    return FALSE;
}

#if WITH_SUSPEND_RESUME

static void
sleeping_cb (MMSleepMonitor *sleep_monitor)
{
    mm_dbg ("Removing devices... (sleeping)");
    mm_base_manager_shutdown (manager, FALSE);
}

static void
resuming_cb (MMSleepMonitor *sleep_monitor)
{
    mm_dbg ("Re-scanning (resuming)");
    mm_base_manager_start (manager, FALSE);
}

#endif

static void
bus_acquired_cb (GDBusConnection *connection,
                 const gchar *name,
                 gpointer user_data)
{
    GError *error = NULL;

    mm_dbg ("Bus acquired, creating manager...");

    /* Create Manager object */
    g_assert (!manager);
    manager = mm_base_manager_new (connection,
                                   mm_context_get_test_plugin_dir (),
                                   !mm_context_get_no_auto_scan (),
                                   mm_context_get_initial_kernel_events (),
                                   mm_context_get_test_enable (),
                                   &error);
    if (!manager) {
        mm_warn ("Could not create manager: %s", error->message);
        g_error_free (error);
        g_main_loop_quit (loop);
        return;
    }
}

static void
name_acquired_cb (GDBusConnection *connection,
                  const gchar *name,
                  gpointer user_data)
{
    mm_dbg ("Service name '%s' was acquired", name);

    /* Launch automatic scan for devices */
    g_assert (manager);
    mm_base_manager_start (manager, FALSE);
}

static void
name_lost_cb (GDBusConnection *connection,
              const gchar *name,
              gpointer user_data)
{
    /* Note that we're not allowing replacement, so once the name acquired, the
     * process won't lose it. */
    if (!name)
        mm_warn ("Could not get the system bus. Make sure "
                 "the message bus daemon is running!");
    else
        mm_warn ("Could not acquire the '%s' service name", name);

    if (manager)
        g_object_set (manager, MM_BASE_MANAGER_CONNECTION, NULL, NULL);

    g_main_loop_quit (loop);
}

int
main (int argc, char *argv[])
{
    GMainLoop *inner;
    GError *err = NULL;
    guint name_id;

    /* Setup application context */
    mm_context_init (argc, argv);

    if (!mm_log_setup (mm_context_get_log_level (),
                       mm_context_get_log_file (),
                       mm_context_get_timestamps (),
                       mm_context_get_relative_timestamps (),
                       mm_context_get_debug (),
                       &err)) {
        g_warning ("Failed to set up logging: %s", err->message);
        g_error_free (err);
        exit (1);
    }

    g_unix_signal_add (SIGTERM, quit_cb, NULL);
    g_unix_signal_add (SIGINT, quit_cb, NULL);

    mm_info ("ModemManager (version " MM_DIST_VERSION ") starting in %s bus...",
             mm_context_get_test_session () ? "session" : "system");

    /* Acquire name, don't allow replacement */
    name_id = g_bus_own_name (mm_context_get_test_session () ? G_BUS_TYPE_SESSION : G_BUS_TYPE_SYSTEM,
                              MM_DBUS_SERVICE,
                              G_BUS_NAME_OWNER_FLAGS_NONE,
                              bus_acquired_cb,
                              name_acquired_cb,
                              name_lost_cb,
                              NULL,
                              NULL);
#if WITH_SUSPEND_RESUME
    {
        MMSleepMonitor *sleep_monitor;

        sleep_monitor = mm_sleep_monitor_get ();
        g_signal_connect (sleep_monitor, MM_SLEEP_MONITOR_SLEEPING, G_CALLBACK (sleeping_cb), NULL);
        g_signal_connect (sleep_monitor, MM_SLEEP_MONITOR_RESUMING, G_CALLBACK (resuming_cb), NULL);
    }
#endif

    /* Go into the main loop */
    loop = g_main_loop_new (NULL, FALSE);
    g_main_loop_run (loop);

    /* Clear the global variable, so that subsequent requests to
     * exit succeed. */
    inner = loop;
    loop = NULL;

    if (manager) {
        GTimer *timer;

        mm_base_manager_shutdown (manager, TRUE);

        /* Wait for all modems to be disabled and removed, but don't wait
         * forever: if disabling the modems takes longer than 20s, just
         * shutdown anyway. */
        timer = g_timer_new ();
        while (mm_base_manager_num_modems (manager) &&
               g_timer_elapsed (timer, NULL) < (gdouble)MAX_SHUTDOWN_TIME_SECS) {
            GMainContext *ctx = g_main_loop_get_context (inner);

            g_main_context_iteration (ctx, FALSE);
            g_usleep (50);
        }

        if (mm_base_manager_num_modems (manager))
            mm_warn ("Disabling modems took too long, "
                     "shutting down with '%u' modems around",
                     mm_base_manager_num_modems (manager));

        g_object_unref (manager);
        g_timer_destroy (timer);
    }

    g_main_loop_unref (inner);

    g_bus_unown_name (name_id);

    mm_info ("ModemManager is shut down");

    mm_log_shutdown ();

    return 0;
}
