#include <stdio.h>
#include <inttypes.h>
#include <string.h>

#include "aboot-tiny.h"
#include "jacana_firmware.h"
#include "jacana_pvt.h"

/*---------------------------------------------------------------------------*/
static int
firmware_read_next_to_cache(firmware_handle_t *firmware)
{
  size_t size = firmware->end_ptr - firmware->read_ptr;
  memmove(firmware->read_ptr - firmware->read_sz, firmware->read_ptr, size);
  firmware->read_ptr -= firmware->read_sz;
  firmware->end_ptr -= firmware->read_sz;
  size_t remainder = firmware->end - firmware->start;
  if(remainder > 0) {
    size_t size = remainder > firmware->read_sz ? firmware->read_sz : remainder;
    int len = jacana_firmware_raw_read(firmware->priv, firmware->start,
                                       (uint8_t *)firmware->middle_ptr, size);
    if(len < 0) {
      return -1;
    }
    firmware->start += len;
    firmware->end_ptr += len;
  }

  return 0;
}
/*---------------------------------------------------------------------------*/
int
jacana_firmware_open(firmware_handle_t *firmware, void *priv)
{
  firmware->priv = priv;
  firmware->start = 0;
  firmware->end = jacana_firmware_raw_get_total_size(priv);

  firmware->data = aboot_tiny_mem_alloc(MAX_READ_CACHE_SZ * 2);
  if(!firmware->data) {
    aboot_tiny_log_printf("Failed: can not alloc data buf\n");
    return -1;
  }

  firmware->read_sz = MAX_READ_CACHE_SZ;
  firmware->middle_ptr = (char *)firmware->data + firmware->read_sz;
  firmware->end_ptr = firmware->middle_ptr + firmware->read_sz;
  firmware->read_ptr = firmware->end_ptr;
  if(firmware_read_next_to_cache(firmware) < 0) {
    goto failed;
  }

  char cmd_line[ABOOT_COMMAND_SZ];
  char magic[9];
  uint32_t size;
  int num;

  if(jacana_firmware_read_line(firmware, cmd_line) <= 0) {
    aboot_tiny_log_printf("Failed: can not read a cmd line\n");
    goto failed;
  }
  num = sscanf(cmd_line, "%08s%" SCNx32, magic, &size);
  if(num != 2 || size > firmware->end) {
    aboot_tiny_log_printf("Failed: cmd line format error\n");
    goto failed;
  }
  firmware->end = (size_t)size;
  if(strcmp(magic, "!JACANA!")) {
    aboot_tiny_log_printf("Magic error: not a valid firmware\n");
    goto failed;
  }

  return 0;

failed:
  aboot_tiny_mem_free(firmware->data);
  firmware->data = NULL;
  return -1;
}
/*---------------------------------------------------------------------------*/
int
jacana_firmware_read_line(firmware_handle_t *firmware, char *line)
{
  while(1) {
    if(firmware->read_ptr < firmware->middle_ptr) {
      const char *p = (const char *)strchr(firmware->read_ptr, '\n');
      if(!p || p >= firmware->end_ptr) {
        return -1;
      }
      int len = p - firmware->read_ptr + 1;
      memcpy(line, firmware->read_ptr, len);
      line[len] = '\0';
      firmware->read_ptr += len;
      if(firmware->read_ptr == firmware->end_ptr) {
        /* firmware download finished, prepare for continue with pvt */
        void *priv = jacana_pvt_raw_open();
        if(!priv) {
          return -1;
        }
        jacana_firmware_raw_close(firmware->priv);
        jacana_firmware_close(firmware);
        if(jacana_pvt_open(firmware, priv) < 0) {
          return -1;
        }
        aboot_tiny_firmware_read_line = jacana_pvt_read_line;
        aboot_tiny_firmware_read_data = jacana_pvt_read_data;
      }
      if(line[0] == '\n') {
        continue;
      } else {
        line[len - 1] = '\0'; /* replace '\n' to '\0' */
        return len - 1;
      }
    } else {
      /* read_ptr >= middle_ptr */
      if(firmware_read_next_to_cache(firmware) < 0) {
        return -1;
      }
    }
  }
}
/*---------------------------------------------------------------------------*/
int
jacana_firmware_read_data(firmware_handle_t *firmware, uint8_t *data, size_t size)
{
  while(1) {
    if(firmware->read_ptr == firmware->end_ptr) {
      return 0;
    }

    if(firmware->read_ptr < firmware->middle_ptr) {
      size_t remainder = firmware->middle_ptr - firmware->read_ptr;
      if(remainder < size) {
        size = remainder;
      }
      memcpy(data, firmware->read_ptr, size);
      firmware->read_ptr += size;
      return size;
    } else {
      /* read_ptr >= middle_ptr */
      if(firmware_read_next_to_cache(firmware) < 0) {
        return -1;
      }
    }
  }
}
/*---------------------------------------------------------------------------*/
void
jacana_firmware_close(firmware_handle_t *firmware)
{
  firmware->priv = NULL;
  firmware->start = 0;
  firmware->end = 0;
  if(firmware->data) {
    aboot_tiny_mem_free(firmware->data);
    firmware->data = NULL;
  }
  firmware->read_sz = 0;
  firmware->read_ptr = NULL;
  firmware->middle_ptr = NULL;
  firmware->end_ptr = NULL;
}
/*---------------------------------------------------------------------------*/
