/* flaneth - flash and ethernet
   Copyright (C) 2007-2012 Stefan Schuermans <stefan@schuermans.info>
   Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
   a BlinkenArea project - http://www.blinkenarea.org/ */

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

#include "apps_tools.h"
#include "debug.h"
#include "dosfs.h"

/**
 * @brief read string from file
 * @param[in] sectorBuf scratch buffer to store a sector
 * @param[in] vi volume information structure
 * @param[in] filename name of file to read
 * @param[out] buf buffer to put string to
 * @param[in] sz size of buffer
 * @return 0 on success, -1 on error
 */
char AppsToolsReadStr(uint8_t sectorBuf[SECTOR_SIZE], VOLINFO *vi,
                      const char *filename, char *buf, unsigned int sz) // (extern)
{
  FILEINFO fi;
  uint32_t len;

  // open file
  if (DFS_OpenFile(vi, (uint8_t *)filename, DFS_READ,
                   sectorBuf, &fi) != DFS_OK) {
    debug_app_cfg_printf("cannot open file %s", filename);
    return -1;
  }

  // read string from file
  if (DFS_ReadFile(&fi, sectorBuf, (uint8_t *)buf, &len, sz - 1) != DFS_OK)
    len = 0;
  if (len > sz - 1)
    len = sz - 1;
  buf[len] = 0; // terminate string
  debug_apps_tools_printf("string read from file %s: %s", filename, buf);
  return 0;
}

/**
 * @brief read MAC address from file
 * @param[in] sectorBuf scratch buffer to store a sector
 * @param[in] vi volume information structure
 * @param[in] filename name of file to read
 * @param[out] mac MAC address read
 * @return 0 on success, -1 on error
 */
char AppsToolsReadMac(uint8_t sectorBuf[SECTOR_SIZE], VOLINFO *vi,
                      const char *filename, unsigned char mac[6]) // (extern)
{
  char bufStr[18];
  unsigned char bufMac[6];

  // get string from file
  if (AppsToolsReadStr(sectorBuf, vi, filename, bufStr, sizeof(bufStr)) != 0)
    return -1;

  // parse string
  if (sscanf(bufStr, "%hhX:%hhX:%hhX:%hhX:%hhX:%hhX",
             &bufMac[0], &bufMac[1], &bufMac[2],
             &bufMac[3], &bufMac[4], &bufMac[5]) != 6) {
    debug_apps_tools_printf("MAC parse error");
    return -1;
  }

  // copy MAC to output
  debug_apps_tools_printf("MAC read: %02hhX:%02hhX:%02hhX:%02hhX:%02hhX:%02hhX",
                          bufMac[0], bufMac[1], bufMac[2],
                          bufMac[3], bufMac[4], bufMac[5]);
  memcpy(mac, bufMac, 6);
  return 0;
}

/**
 * @brief read IP address from file
 * @param[in] sectorBuf scratch buffer to store a sector
 * @param[in] vi volume information structure
 * @param[in] filename name of file to read
 * @param[out] ip IP address read
 * @return 0 on success, -1 on error
 */
char AppsToolsReadIp(uint8_t sectorBuf[SECTOR_SIZE], VOLINFO *vi,
                     const char *filename, unsigned char ip[4]) // (extern)
{
  char bufStr[16];
  unsigned char bufIp[4];

  // get string from file
  if (AppsToolsReadStr(sectorBuf, vi, filename, bufStr, sizeof(bufStr)) != 0)
    return -1;

  // parse string
  if (sscanf(bufStr, "%hhu.%hhu.%hhu.%hhu",
             &bufIp[0], &bufIp[1], &bufIp[2], &bufIp[3]) != 4) {
    debug_apps_tools_printf("IP parse error");
    return -1;
  }

  // copy IP to output
  debug_apps_tools_printf("IP read: %hhu.%hhu.%hhu.%hhu",
                          bufIp[0], bufIp[1], bufIp[2], bufIp[3]);
  memcpy(ip, bufIp, 4);
  return 0;
}

/**
 * @brief read network port from file
 * @param[in] sectorBuf scratch buffer to store a sector
 * @param[in] vi volume information structure
 * @param[in] filename name of file to read
 * @param[out] port network port read
 * @return 0 on success, -1 on error
 */
char AppsToolsReadPort(uint8_t sectorBuf[SECTOR_SIZE], VOLINFO *vi,
                       const char *filename, unsigned short *port) // (extern)
{
  char bufStr[16];
  unsigned short tmpPort;

  // get string from file
  if (AppsToolsReadStr(sectorBuf, vi, filename, bufStr, sizeof(bufStr)) != 0)
    return -1;

  // parse string
  if (sscanf(bufStr, "%hu", &tmpPort) != 1 || tmpPort == 0) {
    debug_apps_tools_printf("port parse error");
    return -1;
  }

  // port to output
  debug_apps_tools_printf("port read: %hu", tmpPort);
  *port = tmpPort;
  return 0;
}

