/*
 * Copyright (C) 2013-2016, Shenzhen Huiding Technology Co., Ltd.
 * All Rights Reserved.
 */
#include "common.h"
#include "ftm.h"
#include "errno.h"
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>

#define TAG "[Fingerprint] "
#ifdef FEATURE_FTM_FINGERPRINT

#define LENS 16

static char *s_FilePath[LENS] = {
    "/sys/devices/soc/11012000.spi/spi_master/spi1/spi1.0/diag/chip_id",
    "/sys/module/fingerprint_id/parameters/dev_id",
};

enum finger_test_result
{
    FINGER_TEST_PASS,
    FINGER_TEST_FAIL,
};

#define mod_to_fingerprint(p) (struct fingerprint *)((char *)(p) + sizeof(struct ftm_module))

struct fingerprint
{
    struct ftm_module *mod;
    text_t title;
    struct itemview *iv;
};

static struct itemview *iv = NULL;

static item_t finger_item[] = {
    item(0, uistr_info_test_pass),
    item(1, uistr_info_test_fail),
    item(-1, NULL)};

int finger_open(const char *path, int fcntl)
{
    int fd = 0;

    fd = open(path, fcntl);
    if (fd < 0)
    {
        LOGD(TAG " [%s] open fd failed, fd = [%d], path =[%s]", __func__, fd, path);
    }
    else
    {
        LOGD(TAG " [%s] open fd pass, fd = [%d], path =[%s]", __func__, fd, path);
    }

    return fd;
}

size_t finger_read(int fd, char *buf, size_t size)
{
    ssize_t s = 0;

    if (fd == 0)
    {
        LOGD(TAG " [%s] fd == 0, failed", __func__);
        return -1;
    }

    s = read(fd, buf, size); //check failed

    LOGD(TAG " [%s] buf = [%s], return [%d]", __func__, buf, s);

    return s;
}

int figner_check(char *buf, size_t size)
{
    int ret = 0;

    if (buf == 0)
    {
        LOGD(TAG " [%s] buf == null, failed", __func__);
        return -1;
    }

    if (!strncmp(buf, "1", 1))
    {
        ret = 0; //pass
    }
    else
    {
        ret = 1; //fail
    }

    LOGD(TAG " [%s] ret = [%d]", __func__, ret);

    return ret;
}

int figner_close(int fd)
{
    int ret = 0;

    if (fd == 0)
    {
        LOGD(TAG " [%s] fd == 0, failed", __func__);
        return -1;
    }

    ret = close(fd);

    return ret;
}

static int fingerprint_test(void)
{
    int fd = 0;
    int result = -1;
    char buf[256];
    int i = 0;

    LOGD(TAG " [%s] enter", __func__);

    for (i = 0; i < LENS; i++)
    {
        if (s_FilePath[i] == 0)
            break;

        fd = finger_open(s_FilePath[i], O_RDONLY);
        if (fd < 0)
        {
            LOGD(TAG " [%s] s_FilePath[%d], %s not exist", __func__, i, s_FilePath[i]);
            continue;
        }

        LOGD(TAG " [%s] s_FilePath[%d], %s exist", __func__, i, s_FilePath[i]);

        finger_read(fd, buf, sizeof(buf));
        LOGD(TAG " [%s] finger_read buf=[%s]", __func__, buf);

        result = figner_check(buf, sizeof(buf));
        LOGD(TAG " [%s] figner_check result=[%d]", __func__, result);

        figner_close(fd);
    }

    LOGD(TAG " [%s] end", __func__);

    return result;
}

int fingerprint_entry(struct ftm_param *param, void *priv)
{
    int err = 0;
    uint8_t get_normal_config_flag = 0;
    uint8_t is_pass = 0;
    enum finger_test_result test_result = FINGER_TEST_FAIL;

    struct fingerprint *fp = (struct fingerprint *)priv;

    LOGE(TAG " [%s] enter", __func__);

    test_result = fingerprint_test();
    if (test_result == FINGER_TEST_PASS)
    {
        is_pass = 1;
    }
    else
    {
        is_pass = 0;
    }

    init_text(&fp->title, param->name, COLOR_YELLOW);

    if (NULL == fp->iv)
    {
        iv = ui_new_itemview();
        if (!iv)
        {
            LOGD(TAG " [%s] No memory for item view", __func__);
            return -1;
        }
        fp->iv = iv;
    }
    iv->set_title(iv, &fp->title);

    if (is_pass)
    {
        LOGI(TAG " [%s] test pass", __func__);
        fp->mod->test_result = FTM_TEST_PASS;
        iv->set_items(iv, finger_item, 0);
        iv->start_menu(iv, 0);
    }
    else
    {
        LOGI(TAG " [%s] test fail", __func__);
        fp->mod->test_result = FTM_TEST_FAIL;
        iv->set_items(iv, finger_item, 1);
        iv->start_menu(iv, 1);
    }

    iv->redraw(iv);
    usleep(500000);
    return 0;
}

int fingerprint_init(void)
{
    int ret = 0;
    struct fingerprint *fp = NULL;
    struct ftm_module *mod = NULL;

    LOGE(TAG " [%s] enter", __func__);

    mod = ftm_alloc(ITEM_FINGERPRINT_TEST, sizeof(struct fingerprint));
    if (!mod)
    {
        LOGD(TAG " [%s] mod alloc failed", __func__);
        return -ENOMEM;
    }

    fp = mod_to_fingerprint(mod);
    if (!fp)
    {
        LOGD(TAG " [%s] fp NULL failed", __func__);
        return -ENOMEM;
    }

    fp->mod = mod;

    ret = ftm_register(mod, fingerprint_entry, (void *)fp);
    if (ret)
    {
        LOGD(TAG "%s -register fingerprint_entry fail!! ret:%d\n", __FUNCTION__, ret);
    }

    LOGD(TAG " [%s] exit, ret = %d", __func__, ret);
    return ret;
}

#endif // FEATURE_FTM_FINGERPRINT
