/*
 * wiegand.c
 *
 *  Created on:
 *      Author:
 */

#include <stdio.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <freertos/queue.h>
#include <wiegand.h>
#include <esp_log.h>
#include <string.h>
#include <evse_api.h>
#include <ocpp.h>

static const char *TAG = "Wiegand_reader";

static wiegand_reader_t reader;
static QueueHandle_t queue = NULL;

#define CONFIG_EXAMPLE_BUF_SIZE 50

// Single data packet
typedef struct
{
    uint8_t data[CONFIG_EXAMPLE_BUF_SIZE];
    size_t bits;
} data_packet_t;

// callback on new data in reader
static void reader_callback(wiegand_reader_t *r)
{
    // you can decode raw data from reader buffer here, but remember:
    // reader will ignore any new incoming data while executing callback

    // create simple undecoded data packet
    data_packet_t p;
    p.bits = r->bits;
    memcpy(p.data, r->buf, CONFIG_EXAMPLE_BUF_SIZE);

    // Send it to the queue
    xQueueSendToBack(queue, &p, 0);
}

static void wiegand_task(void *arg)
{
    // Create queue
    queue = xQueueCreate(5, sizeof(data_packet_t));
    if (!queue)
    {
        ESP_LOGE(TAG, "Error creating queue");
        ESP_ERROR_CHECK(ESP_ERR_NO_MEM);
    }

    // Initialize reader
    ESP_ERROR_CHECK(wiegand_reader_init(&reader, 19, 18,
                                        true, CONFIG_EXAMPLE_BUF_SIZE, reader_callback, WIEGAND_MSB_FIRST, WIEGAND_LSB_FIRST));

    data_packet_t p;
    while (1)
    {
        ESP_LOGI(TAG, "Waiting for Wiegand data...");
        xQueueReceive(queue, &p, portMAX_DELAY);

        // dump received data
        // ESP_LOGI(TAG, "==========================================");
        ESP_LOGI(TAG, "Bits received: %d\n", p.bits);
        ESP_LOGI(TAG, "Received data:");
        int bytes = p.bits / 8;
        int tail = p.bits % 8;
        for (size_t i = 0; i < bytes + (tail ? 1 : 0); i++)
            printf(" 0x%02x", p.data[i]);

        char str[20];
        if (p.bits == 26)
        {
            evse_authorize();
            /*
            sprintf(str, "%03d%03d%03d", p.data[0], p.data[1], p.data[2]);

            if (ocpp_is_TransactionActive())
            {
                ocpp_end_transaction(str);
            }
            else
            {
                ocpp_begin_transaction(str);
            }*/
        }
        else if (p.bits == 34)
        {
            evse_authorize();
            /*
            sprintf(str, "%03d%03d%03d%03d", p.data[0], p.data[1], p.data[2], p.data[3]);

            if (ocpp_is_TransactionActive())
            {
                ocpp_end_transaction(str);
            }
            else
            {
                ocpp_begin_transaction(str);
            }
            */
        }
    }

    // ESP_LOGI(TAG, "==========================================");
}

/*
static void wiegand_task(void *arg)
{

    while (1)
    {
        vTaskDelay(pdMS_TO_TICKS(15000));
        ocpp_begin_transaction("AAAAAA");

        vTaskDelay(pdMS_TO_TICKS(15000));
        ocpp_end_transaction("AAAAAA");

        vTaskDelay(pdMS_TO_TICKS(15000));
        ocpp_begin_transaction("AAAAAB");

        vTaskDelay(pdMS_TO_TICKS(15000));
        ocpp_end_transaction("AAAAAB");
    }
}
*/
void initWiegand()
{
    ESP_LOGI(TAG, "Starting wiegand");
    // xTaskCreate(&wiegand_task, "wiegandtask", 8192, NULL, 5, NULL);
    xTaskCreate(wiegand_task, TAG, configMINIMAL_STACK_SIZE * 4, NULL, 5, NULL);
}