/* Copyright (C) 2015 The Android Open Source Project
**
** This software is licensed under the terms of the GNU General Public
** License version 2, as published by the Free Software Foundation, and
** may be copied, distributed, and modified under those terms.
**
** 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.
*/

#include "android/hw-fingerprint.h"
#include "android/utils/debug.h"
#include "android/utils/misc.h"
#include "android/utils/system.h"
#include "android/hw-qemud.h"
#include "android/globals.h"
#include "hw/hw.h"

#include <math.h>

#define  E(...)    derror(__VA_ARGS__)
#define  W(...)    dwarning(__VA_ARGS__)
#define  D(...)  VERBOSE_PRINT(init,__VA_ARGS__)
#define  V(...)  VERBOSE_PRINT(init,__VA_ARGS__)

/***********************************************************************************

            All the declarations

***********************************************************************************/

typedef struct HwFingerprintClient   HwFingerprintClient;

typedef struct {
    QemudService*           qemu_listen_service;
    HwFingerprintClient*    fp_clients;
    int32_t     fingerid;
    int32_t     finger_is_on_sensor;
} HwFingerprintService;

struct HwFingerprintClient {
    HwFingerprintClient*    next;
    HwFingerprintService*          fp;
    QemudClient*            qemu_client;
};

static void
_hwFingerprintClient_recv(void* opaque, uint8_t* msg, int msglen,
                      QemudClient*  client );

static void
_hwFingerprintClient_close(void* opaque);

static HwFingerprintClient*
_hwFingerprintClient_new( HwFingerprintService*  fp);

/* the only static variable */
static HwFingerprintService _fingerprintState[1];

static void _hwFingerprint_send();

static QemudClient*
_hwFingerprint_connect(void*  opaque,
                    QemudService*  service,
                    int  channel,
                    const char* client_param);
static void
_hwFingerprintClient_removeFromList(HwFingerprintClient** phead,
        HwFingerprintClient* target);

static void
_hwFingerprint_save(QEMUFile*  f, QemudService*  sv, void*  opaque);

static int
_hwFingerprint_load(QEMUFile*  f, QemudService*  sv, void*  opaque);
/***********************************************************************************

            All the public methods

***********************************************************************************/

void
android_hw_fingerprint_init( void )
{
    HwFingerprintService*  fp = _fingerprintState;

    if (fp->qemu_listen_service == NULL) {
        fp->qemu_listen_service = qemud_service_register("fingerprintlisten", 0, fp,
                _hwFingerprint_connect, _hwFingerprint_save, _hwFingerprint_load);
        D("%s: fingerprint qemud listen service initialized\n", __FUNCTION__);
    }
}

void
android_hw_fingerprint_touch(int fingerid)
{
    HwFingerprintService*  fp = _fingerprintState;
    D("touched fingerprint sensor with finger id %d\n", fingerid);
    fp->fingerid = fingerid;
    fp->finger_is_on_sensor = 1;
    _hwFingerprint_send();
}

void
android_hw_fingerprint_remove()
{
    HwFingerprintService*  fp = _fingerprintState;
    D("finger removed from the fingerprint sensor\n");
    fp->finger_is_on_sensor = 0;
    _hwFingerprint_send();
}

/***********************************************************************************

            All the static methods

***********************************************************************************/

static void
_hwFingerprint_save(QEMUFile*  f, QemudService*  sv, void*  opaque)
{
    HwFingerprintService* fp = opaque;
    qemu_put_be32(f, fp->fingerid);
    qemu_put_be32(f, fp->finger_is_on_sensor);
}

static int
_hwFingerprint_load(QEMUFile*  f, QemudService*  sv, void*  opaque)
{
    HwFingerprintService* fp = opaque;
    fp->fingerid = qemu_get_be32(f);
    fp->finger_is_on_sensor = qemu_get_be32(f);
    return 0;
}

static void
_hwFingerprint_send()
{
    HwFingerprintService*  fp = _fingerprintState;
    HwFingerprintClient*    fp_client = fp->fp_clients;
    if (!fp_client)
        return;

    char buffer[128];
    if (fp->finger_is_on_sensor) {
        /* send back the finger id that is on the finger print sensor */
        snprintf(buffer, sizeof(buffer) - 1, "on:%d", fp_client->fp->fingerid);
    } else {
        snprintf(buffer, sizeof(buffer) - 1, "off");
    }
    qemud_client_send(fp_client->qemu_client, (const uint8_t*)buffer,
            strlen(buffer)+1 /*add 1 for '\0'*/);
}

static QemudClient*
_hwFingerprint_connect(void*  opaque,
                    QemudService*  service,
                    int  channel,
                    const char* client_param)
{
    HwFingerprintService*  fp = opaque;
    HwFingerprintClient*    fp_client = _hwFingerprintClient_new(fp);
    QemudClient*    client  = qemud_client_new(service, channel, client_param, fp_client,
                                                _hwFingerprintClient_recv,
                                                _hwFingerprintClient_close,
                                                NULL, /* no save */
                                                NULL /* no load */ );
    qemud_client_set_framing(client, 1);
    fp_client->qemu_client = client;

    D("%s: connect finger print listen is called\n", __FUNCTION__);
    return client;
}

static void
_hwFingerprintClient_recv(void* opaque, uint8_t* msg, int msglen,
                      QemudClient*  client )
{
    /* HwFingerprintClient*       fp_client = opaque; */
    D("got message from guest system fingerprint HAL\n");
}

static HwFingerprintClient*
_hwFingerprintClient_new( HwFingerprintService*  fp)
{
    HwFingerprintClient*  fp_client;
    ANEW0(fp_client);
    fp_client->fp = fp;
    fp_client->next = fp->fp_clients;
    fp->fp_clients = fp_client;
    return fp_client;
}

static void
_hwFingerprintClient_close(void* opaque)
{
    HwFingerprintClient*       fp_client = opaque;
    if (fp_client->fp) {
        HwFingerprintClient** pnode = &fp_client->fp->fp_clients;
        _hwFingerprintClient_removeFromList(pnode, fp_client);
        fp_client->next = NULL;
        fp_client->fp = NULL;
    }
    AFREE(fp_client);
}

static void
_hwFingerprintClient_removeFromList(HwFingerprintClient** phead, HwFingerprintClient* target)
{
    for (;;) {
        HwFingerprintClient* node = *phead;
        if (node == NULL)
            break;
        if (node == target) {
            *phead = target->next;
            break;
        }
        phead = &node->next;
    }
}
