#include <licq/licq_constants.h>
#include <licq/licq_events.h>
#include <licq/licq_icqd.h>
#include <licq/licq_log.h>
#include <licq/licq_plugin.h>
#include <licq/licq_user.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include "ledmsg.h"

using namespace std;

int PluginEnabled = 0;

void sendmsg(const char *msg)
{
    int fd;
    struct sockaddr_in6 addr;
    struct ledmsg_t m;

    if((fd = socket(PF_INET6, SOCK_DGRAM, 0)) == -1)
        return;

    memset(&addr, 0, sizeof(addr));
    addr.sin6_family = AF_INET6;
    addr.sin6_port = htons(FP_LED_PORT);
    addr.sin6_addr = in6addr_loopback;

    memset(&m, 0, sizeof(m));
    m.speed = 20;
    m.priority = FP_PRIO_ICQ;
    m.times = 1;
    m.flags = FP_FLAG_SCROLL | FP_FLAG_BRIGHT;
    sprintf((char*)m.msg, "ICQ %s", msg);

    sendto(fd, &m, sizeof(m), 0, (struct sockaddr *)&addr, sizeof(addr));
    close(fd);
}

const char *LP_Usage()
{
    static const char usage[] = "No options for this plugin.";
    return usage;
}

const char *LP_Name()
{
    static const char name[] = "LedFront Plugin";
    return name;
}

/*
const char *LP_ConfigFile()
{
    static const char name[] = "licq_fp.conf";
    return name;
}
*/

const char *LP_Version()
{
    static const char version[] = "0.01";
    return version;
}

const char *LP_Status()
{
    static const char status_running[] = "running";
    static const char status_disabled[] = "disabled";
    return PluginEnabled ? status_running : status_disabled;
}

const char *LP_Description()
{
    static const char desc[] = "Displays information on Front display";
    return desc;
}

bool LP_Init(int argc, char **argv)
{
    gLog.Info("LedFront plugin initializing.\n");
    return true;
}

void HandleSignal(CICQSignal *s)
{
    ICQUser *u;
    string username;
    switch(s->Signal())
    {
        case SIGNAL_UPDATExUSER:
            u = gUserManager.FetchUser(s->Id(), s->PPID(), LOCK_R);
            if(!u)
            {
                gLog.Warn("User %ld not found.\n", s->Uin());
                return;
            }
            username = u->GetAlias();
            gUserManager.DropUser(u);

            /*
            // user fetched our auto-response
            if(s->SubSignal() == USER_EVENTS && s->Argument() == 0)
            {

            }
            */

            // user sent a message
            if(s->SubSignal() == USER_EVENTS && s->Argument() > 0)
            {

                sendmsg(username.c_str());
            }

            /*
            // user changed status
            if(s->SubSignal() == USER_STATUS)
            {

            }
            */
            break;
        case SIGNAL_LOGOFF:
            break;
        case SIGNAL_LOGON:
            break;
        case SIGNAL_ADDxSERVERxLIST:
            break;
        case SIGNAL_UI_MESSAGE:
            break;
        case SIGNAL_UPDATExLIST:
            break;
    }
}

int LP_Main(CICQDaemon *LicqDaemon)
{
//    int p = LicqDaemon->RegisterPlugin(SIGNAL_UPDATExUSER | SIGNAL_LOGON| SIGNAL_LOGOFF);
    int p = LicqDaemon->RegisterPlugin(SIGNAL_UPDATExUSER);
    if(p == -1)
    {
        gLog.Warn("LedFront plugin got an invalid Pipe.\n");
        return 1;
    }

    PluginEnabled = 1;

    while(1)
    {
        char buf[16];
        CICQSignal *s;
        ICQEvent *e;

        read(p, buf, 1);
        switch(buf[0])
        {
            case PLUGIN_SIGNAL: // signal is pending
                s =  LicqDaemon->PopPluginSignal();
                if(s) {
                    if(PluginEnabled)
                        HandleSignal(s);
                    delete s;
                }
                break;
            case PLUGIN_EVENT: // event is pending
                gLog.Warn("LedFront plugin got unexpected event.\n");
                e = LicqDaemon->PopPluginEvent();
                if(e)
                    delete e;
                break;
            case PLUGIN_SHUTDOWN: // time to shutdown
                gLog.Info("LedFront plugin is shutting down.\n");
                LicqDaemon->UnregisterPlugin();
//                LicqDaemon->Shutdown();
//                LP_Exit(0);
                return 0;
            case '0':
                PluginEnabled = 0;
                gLog.Info("LedFront plugin disabled.\n");
                break;
            case '1':
                gLog.Info("LedFront plugin enabled.\n");
                PluginEnabled = 1;
                break;
            default:
                gLog.Warn("LedFront plugin got an unknown message type %i\n", buf[0]);
        }
    }
}

