/* Copyright 2016 tgil All Rights Reserved */

#include <string.h>
#include "blog.h"
#include "led.h"
#include "app_error.h"
#include "pstorage.h"

#define BLOG_ENTRIES 512
#define BLOG_SIZE (BLOG_ENTRIES*sizeof(uint16_t))

static uint16_t m_blog_table[BLOG_ENTRIES];
static volatile uint8_t m_ps_flag = 0;
pstorage_handle_t m_base_handle;
static int m_blog_current_entry;
static void blog_cb_handler(pstorage_handle_t * handle, uint8_t op_code,
              uint32_t result, uint8_t * p_data, uint32_t data_len)
{
  switch(op_code)
  {
    case PSTORAGE_STORE_OP_CODE:
      m_ps_flag = 2;
    break;
    case PSTORAGE_LOAD_OP_CODE:
      m_ps_flag = 3;
    break;
    case PSTORAGE_CLEAR_OP_CODE:
      m_ps_flag = 4;
    break;
    case PSTORAGE_UPDATE_OP_CODE:
      m_ps_flag = 5;
    break;
    default:
      m_ps_flag = 1;
    break;
  }
}

int blog_init()
{
  uint32_t retval;
  retval = pstorage_init();
  pstorage_handle_t page_handle;
  memset(m_blog_table, 0, BLOG_SIZE);
  if( retval == NRF_SUCCESS )
  {
    //register burn in log
    pstorage_module_param_t param;
    param.block_size = BLOG_SIZE;
    param.block_count = 1;
    param.cb = blog_cb_handler;
    retval = pstorage_register(&param, &m_base_handle);
    if (retval == NRF_SUCCESS)
    {
      // Registration successful.
      //read the value of the log
      m_ps_flag = 0;
      retval = pstorage_block_identifier_get(&m_base_handle, 0, &page_handle);
      if( retval == NRF_SUCCESS )
      {
        retval = pstorage_load((uint8_t*)m_blog_table, &page_handle, BLOG_SIZE, 0);
        if( retval == NRF_SUCCESS )
        {
          while(m_ps_flag == 0); //wait for the operation to complete
        }
        m_blog_current_entry = blog_get_entries();
      }
    }
  }
  return retval;
}

uint16_t blog_get_entries()
{
  int i;
  for(i=0; i < BLOG_ENTRIES; i++)
  {
    if( m_blog_table[i] == 0xFFFF )
    {
      return i;
    }
  }
  return i;
}

 int blog_is_complete()
{
  if( blog_get_entries() < BLOG_ENTRIES )
  {
    return 0;
  }
  return 1;
}

void blog_set_entry(uint16_t entry)
{
  if( m_blog_current_entry < BLOG_ENTRIES )
  {
    m_blog_table[m_blog_current_entry] = entry;
    m_blog_current_entry++;
  }
}

uint16_t blog_current_entry()
{
  return m_blog_current_entry;
}

int blog_save()
{
  uint32_t retval;
  //save the blog to flash
  pstorage_handle_t page_handle;
  //clear the blog
  retval = pstorage_block_identifier_get(&m_base_handle, 0, &page_handle);
  if( retval != NRF_SUCCESS )
  {
    return -1;
  }
  m_ps_flag = 0;
  retval = pstorage_clear(&page_handle, BLOG_SIZE);
  if( retval != NRF_SUCCESS )
  {
    return -2;
  }
  if( retval == NRF_SUCCESS )
  {
    while(m_ps_flag == 0); //wait for the operation to complete
  }
  if( retval == NRF_SUCCESS )
  {
    m_ps_flag = 0;
    retval = pstorage_store(&page_handle, (uint8_t*)m_blog_table, BLOG_SIZE, 0);
    if( retval == NRF_SUCCESS )
    {
      while(m_ps_flag == 0); //wait for the operation to complete
    } 
    else 
    {
      return -3;
    }
  }
  return retval;
}

void blog_clear()
{
  //clear the burn in log
}

int blog_get_size()
{
  return BLOG_ENTRIES;
}

uint16_t blog_get(int entry)
{
  return m_blog_table[entry];
}