/*
 *
 *  Connection Manager
 *
 *  Copyright (C) 2015 Nest Labs, Inc. All rights reserved.
 *
 *    Author: Andrew LeCain <alecain@nestlabs.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
 *
 */

#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stdio.h>
#include <poll.h>

#include <unistd.h>
#include <pthread.h>
#include <glib.h>


#define CONNMAN_API_SUBJECT_TO_CHANGE
#include <connman/plugin.h>
#include <connman/device.h>
#include <connman/network.h>
#include <connman/inet.h>
#include <connman/dbus.h>
#include <connman/notifier.h>
#include <connman/log.h>
#include <connman/technology.h>
#include <connman/service.h>
#include <connman/ipconfig.h>


#undef DBG
#define DBG(fmt, arg...) \
    connman_debug("%s:%s() " fmt, \
            __FILE__, __FUNCTION__ , ## arg);


static GList *sleep_queue;
static GList *wake_queue;

typedef struct event_s{
        void *owner;
        GList *q;
        time_t valid_until;
}event_t;

gboolean process_queues(gpointer user_data);

gint owner_equals(gconstpointer a, gconstpointer b)
{
        event_t *e = (event_t*) a;
        if (e->owner == b){
                return 0;
        }
        return -1;
}

gint event_compare(gconstpointer aEvent, gconstpointer bEvent)
{
        event_t* a = (event_t*) aEvent;
        event_t* b = (event_t*) bEvent;
        return a->valid_until < b->valid_until;
}

void sleep_event(void *identifier, int cansleep, time_t valid_until)
{

        DBG("Sleep event: can%s sleep until %d\n",cansleep ? "" : "'t" , valid_until);
        //remove any previous entries owned by current identifier
        GList* entry = g_list_find_custom(wake_queue, identifier, &owner_equals);

        if (entry)
        {
                DBG("Found entry in wake queue");
                free(entry->data);
                wake_queue = g_list_delete_link(wake_queue, entry);
        }
        else
        {
                entry = g_list_find_custom(sleep_queue, identifier, &owner_equals);
                if (entry){
                        DBG("Found entry in sleep queue");
                        free(entry->data);
                        sleep_queue = g_list_delete_link(sleep_queue, entry);
                }
        }

        DBG("pruned previous requests\n");

        //make a new event
        event_t *new_event = (event_t *)malloc(sizeof (event_t));
        if (new_event == NULL){
                return;
        }

        new_event->owner = identifier;
        new_event->valid_until = valid_until;

        DBG("inserting new request\n");
        if(cansleep)
        {
                //insert entry into sleep queue
                new_event->q = sleep_queue;
                sleep_queue = g_list_insert(sleep_queue, new_event, -1);

        }
        else
        {
                //insert entry into wake queue
                new_event->q = wake_queue;
                wake_queue = g_list_insert(wake_queue, new_event, -1);
        }
        DBG("added new request\n");

        process_queues(NULL);
}



gint is_expired(gconstpointer data, gconstpointer user_data)
{


        event_t *e = (event_t*) data;
        if ( e  && ( e->valid_until <= time(NULL))){
                return 0;
        }
        return -1;
}


gboolean process_queues(gpointer user_data)
{

        //sort queues
        DBG("sorting queues\n");
        sleep_queue = g_list_sort(sleep_queue, &event_compare);
        wake_queue = g_list_sort(wake_queue, &event_compare);
        //go through each queue and dump anything that has expired.

        DBG("sleep q len: %d, wake q len: %d\n", g_list_length(sleep_queue), g_list_length(wake_queue));

        DBG("cleaning out queues");
        GList* entry;
        while (NULL != (entry = g_list_find_custom(sleep_queue, NULL , &is_expired)))
        {
                DBG("Passed sleep point%d", ((event_t*) (entry->data))->valid_until);
                free(entry->data);
                sleep_queue = g_list_delete_link(sleep_queue, entry);
        }
        while (NULL != (entry = g_list_find_custom(wake_queue, NULL, &is_expired)))
        {
                DBG("Passed wake point %d", ((event_t *) (entry->data))->valid_until);
                free(entry->data);
                wake_queue = g_list_delete_link(wake_queue, entry);
        }

        DBG("sleep q len: %d, wake q len: %d\n", g_list_length(sleep_queue), g_list_length(wake_queue));

        DBG("checking wake queue\n");
        //check wake queue for ANYTHING.
        if (wake_queue)
        {
                event_t *e = wake_queue->data;
                //we can't sleep until at least e->valid_until
                //Stay awake and reschedule for then.
                DBG("staying awake for %d seconds", e->valid_until-time(NULL));
                g_timeout_add_seconds(e->valid_until, process_queues, NULL);
        }
        else
        {
                //nothing is holding us awake-- maybe we can sleep
                DBG("checking sleep queue\n");
                if (sleep_queue)
                {
                        event_t *e = sleep_queue->data;
                        //There is a valid wake time! We can sleep til then
                        DBG("Sleeping for %d seconds", e->valid_until-time(NULL));
                        //system_sleep_until(e->valid_until);
                }
                //else: indeterminiate. Probably shouldn't sleep.
        }

        return FALSE;
}

static struct connman_notifier notifier = {
        .name                   = "sleepplugin",
        .priority               = CONNMAN_NOTIFIER_PRIORITY_DEFAULT,
        .default_changed        = NULL,
        .service_add            = NULL,
        .service_remove         = NULL,
        .service_enabled        = NULL,
        .offline_mode           = NULL,
        .proxy_changed          = NULL,
        .service_state_changed  = NULL,
        .ipconfig_changed       = NULL,
        .sleep_event                    = &sleep_event,
        .idle_state             = NULL,
};

static int sleepplugin_init(void)
{

        DBG("");

        sleep_queue = NULL;
        wake_queue = NULL;

        connman_notifier_register(&notifier);

        return 0;
}

static void sleepplugin_exit(void)
{
        g_list_free_full(sleep_queue, free);
        g_list_free_full(wake_queue, free);
        DBG("");

}

CONNMAN_PLUGIN_DEFINE(sleepplugin, "connman sleep plugin", CONNMAN_VERSION,
                CONNMAN_PLUGIN_PRIORITY_DEFAULT, sleepplugin_init, sleepplugin_exit)
