/*****************************************************************************
* Copyright (c) [2019-2021], Netobjex INC
* All rights reserved.
*
* File:    task_borrower.c
* Summary: borrower Task
*
*/

#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "error_defs.h"

#include "task_borrower.h"
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include "timers.h"

#include "tasks.h"
#include "button_manager.h"
#include "boards.h"
#include "nrf_drv_gpiote.h"
#include "nrf_drv_ppi.h"
#include "nrf_drv_timer.h"

#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"

#include "product_config.h"
#include "borrower.h"
#include "main.h"
#include "borrower_protocol.h"
#include "psf_uart.h"
#include "max17211_i2c.h"


/* Task Configuration */
StaticTask_t task_borrower_tcb;

/* Buffer that the task being created will use as its stack.  Note this is
an array of StackType_t variables.  The size of StackType_t is dependent on
the RTOS port. */
StackType_t borrower_stack[ BORROWER_TASK_STACK_SIZE ];

static QueueHandle_t borrower_queue_handle = NULL;

static void borrower_task( void *pvParameters );
err_rc_t borrower_task_queue_event(BORROWER_TASK_EVENTS_t evt);
void rssi_change_timer_callback1( TimerHandle_t xTimer );
void max17211_timer_callback( TimerHandle_t xTimer );

static void water_flow_stop(void);
static void water_flow_start(void);

/* LED Stack Queue */
#define QUEUE_LENGTH    10
#define ITEM_SIZE       sizeof( BORROWER_TASK_EVENTS_t )

/* The variable used to hold the queue's data structure. */
static StaticQueue_t xStaticQueue;

/* The array to use as the queue's storage area.  This must be at least
uxQueueLength * uxItemSize bytes. */
uint8_t borrower_queue_storage_area[ QUEUE_LENGTH * ITEM_SIZE ];


volatile TaskHandle_t borrower_task_handle = NULL;


char session_id1[16];
static uint16_t timeSinceStart = 0;                                     // in seconds
static float lastWaterConsumption = 0;
static uint32_t lasttotalPulseCount = 0;
static uint32_t lastPulseCount = 0;
int8_t rssi_val_change1;

static const nrf_drv_timer_t m_timer1 = NRF_DRV_TIMER_INSTANCE(1);
static const nrf_drv_timer_t m_timer2 = NRF_DRV_TIMER_INSTANCE(2);

static nrf_ppi_channel_t m_ppi_channel1;
static nrf_ppi_channel_t m_ppi_channel2;

static void process_timer_event(void);
static void borrower_init(void);

static TimerHandle_t rssi_change_timer_handle;
static StaticTimer_t rssi_change_timer;

static TimerHandle_t max17211_handle;
static StaticTimer_t max17211_timer;

/**
 * @brief Initializes the borrower Task
 *
 * @return RESULT_SUCCESS if initialization completed, otherwise error
 */
err_rc_t init_borrower_task(void)
{
    err_rc_t rc = RESULT_SUCCESS;
    do {
        /* Start the two tasks as described in the comments at the top of this
        file. */
        borrower_task_handle = xTaskCreateStatic(
                                 borrower_task,       /* Function that implements the task. */
                                 "borrower",          /* Text name for the task. */
                                 BORROWER_TASK_STACK_SIZE,      /* Number of indexes in the borrower_stack array. */
                                 ( void * ) 1,    /* Parameter passed into the task. */
                                 BORROWER_TASK_PRIORITY,/* Priority at which the task is created. */
                                 borrower_stack,          /* Array to use as the task's stack. */
                                 &task_borrower_tcb );  /* Variable to hold the task's data structure. */

        if(borrower_task_handle == NULL) {
            rc = RESULT_ERROR_FAILURE;
            break;
        }

        /* Create a queue */
        borrower_queue_handle = xQueueCreateStatic( QUEUE_LENGTH,
                              ITEM_SIZE,
                              borrower_queue_storage_area,
                              &xStaticQueue );

        if(borrower_queue_handle == NULL) {
            rc = RESULT_ERROR_FAILURE;
            break;
        }


        rssi_change_timer_handle = xTimerCreateStatic("RssiTimer",
                               20000,
                               pdFALSE,
                               ( void * ) 0,
                               rssi_change_timer_callback1,
                               &rssi_change_timer);

        if( rssi_change_timer_handle == NULL ) {
            /* The timer was not created */
            rc = RESULT_ERROR_FAILURE;
            break;
        }

        max17211_handle = xTimerCreateStatic("Max17211Timer",
                               10000,
                               pdTRUE,
                               ( void * ) 0,
                               max17211_timer_callback,
                               &max17211_timer);

        if( max17211_handle == NULL ) {
            /* The timer was not created */
            rc = RESULT_ERROR_FAILURE;
            break;
        }

    } while(0);

    return rc;
}


/**
 * @brief Queues an event to be processed by the borrower Task
 *
 * @param evt is the event to queue
 *
 * @return RESULT_SUCCESS if initialization completed, otherwise error
 */
err_rc_t borrower_task_queue_event(BORROWER_TASK_EVENTS_t evt)
{
    err_rc_t rc = RESULT_SUCCESS;

    BORROWER_TASK_EVENTS_t queue_evt = evt;

    BaseType_t result =  xQueueSendFromISR(borrower_queue_handle,
                                           &queue_evt,
                                           NULL);

    if(result != pdTRUE) {
        rc = RESULT_ERROR_FAILURE;
    }

    return rc;
}

/**
 * @brief Main borrower Task thread
 *
 * @param pvParameters unused
 *
 *
 */
static void borrower_task( void *pvParameters )
{
    BORROWER_TASK_EVENTS_t evt;
    btnmgr_return_t btrc;
    /* Remove compiler warning about unused parameter. */
    ( void ) pvParameters;

  //  borrower_init();


    if(xTimerStart(max17211_handle, 0 ) != pdPASS ) {
        // The timer could not be set into the Active state.
    }
      
    while(1) 
    {
        xQueueReceive( borrower_queue_handle, &evt, portMAX_DELAY );

        switch(evt) 
        {
            case BORROWER_TASK_EVT_TIMER:
               // process_timer_event();
                break;

            case BORROWER_TASK_EVT_SETTING_CMD:
                borrower_process_ble_setting_msg(get_rcbr_rcv_buffer(), get_rcbr_rcv_cnt());
                break;

            case BORROWER_TASK_EVT_NOTIF_EN:
                /* Notification is enabled, so report the current status */
                borrower_report_current_status();

        }
    }
}


/**@brief water flow measurement setup
 *
 */
static void borrower_init(void) 
{
    borrower_load_settings();

}

void rssi_change_timer_callback1( TimerHandle_t xTimer )
{
    borrower_task_queue_event(BORROWER_TASK_EVT_NOTIF_EN);
    rssi_val_change1 = 1;
}

void max17211_timer_callback( TimerHandle_t xTimer )
{

    get_max17201_data();
    borrower_task_queue_event(BORROWER_TASK_EVT_NOTIF_EN);
}
