///
/// @file cwglib.h
/// @authors k. headley
/// @date 05 dec 2019

/// Carbon Wave Glider client library API

/// @sa doxygen-examples.c for more examples of Doxygen markup


/////////////////////////
// Terms of use
/////////////////////////
/*
 Copyright Information
  
 Copyright 2002-2019 MBARI
 Monterey Bay Aquarium Research Institute, all rights reserved.
 
 Terms of Use
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 3 of the License, or
 (at your option) any later version. You can access the GPLv3 license at
 http://www.gnu.org/licenses/gpl-3.0.html
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details
 (http://www.gnu.org/licenses/gpl-3.0.html)
 
 MBARI provides the documentation and software code "as is", with no warranty,
 express or implied, as to the software, title, non-infringement of third party
 rights, merchantability, or fitness for any particular purpose, the accuracy of
 the code, or the performance or results which you may obtain from its use. You
 assume the entire risk associated with use of the code, and you agree to be
 responsible for the entire cost of repair or servicing of the program with
 which you are using the code.
 
 In no event shall MBARI be liable for any damages, whether general, special,
 incidental or consequential damages, arising out of your use of the software,
 including, but not limited to, the loss or corruption of your data or damages
 of any kind resulting from use of the software, any prohibited use, or your
 inability to use the software. You agree to defend, indemnify and hold harmless
 MBARI and its officers, directors, and employees against any claim, loss,
 liability or expense, including attorneys' fees, resulting from loss of or
 damage to property or the injury to or death of any person arising out of the
 use of the software.
 
 The MBARI software is provided without obligation on the part of the
 Monterey Bay Aquarium Research Institute to assist in its use, correction,
 modification, or enhancement.
 
 MBARI assumes no responsibility or liability for any third party and/or
 commercial software required for the database or applications. Licensee agrees
 to obtain and maintain valid licenses for any additional third party software
 required.
 */

// include guard (recommended)
#ifndef CWGLIB_H
#define CWGLIB_H

/////////////////////////
// Includes 
/////////////////////////


#include "iowserial.h"
#include <stdint.h>


#if defined(__PIC24FJ256GA106__) || defined(__PIC24FJ256GA606__) || defined(__PIC24FJ1024GA606__)

#elif defined(__WIN32) || defined(_WIN64)

//#include "stdafx.h"
#include <Windows.h>

#elif defined(__unix__) || defined(__APPLE__) || defined(__CYGWIN__)
#include <termios.h>
#include <unistd.h>
#endif


/////////////////////////
// Macros
/////////////////////////

#define CWG_CMD_BUF_BYTES 256
#define CWG_IO_BUF_BYTES 2048
#define CWG_LOG_SEEK_SEC 1
#define CWG_FGET_LASTN_RETRIES 3
#define CWG_FGET_N_RETRIES 3

/// @def LINEND
/// @brief POSIX line ending
#define LINEEND "\n"
#define CRLF "\r\n"
#define CWG_PROMPT ">>"
#define CMD_LS "ls"
#define CMD_RM "rm"
#define CMD_CRON_DISABLE "cron -"
#define CMD_CRON_SUSPEND(ms) "cron -"#ms
#define CMD_CRON_RESUME "cron +"
#define CMD_CRON_NEXT "cron x"
#define CMD_HOST_ECHO_DIS "set var echo 1"
#define CMD_HOST_ECHO_EN "set var echo 3"
#define CMD_HOST_PROMPT_DIS "set var prompt 1"
#define CMD_HOST_PROMPT_EN "set var prompt 3"
#define CMD_CAT "cat"
#define CMD_LCAT "lcat"
#define CMD_LAST_SAMPLE(o) "lcat Z l1 dbg:0 out:"#o
#define CMD_LAST_NSAMPLE(n,o) "lcat Z l"#n" dbg:0 out:"#o
#define CMD_LAST_SCSAMPLE(s,c,o) "lcat Z s"#s" c"#c" dbg:0 out:"#o
#define CMD_LAST_NTO_SEC(n) (n*(1+CWG_LOG_SEEK_SEC))
#define CMD_CLAST_SAMPLE "cat r:-,1"
#define CMD_CLAST_NSAMPLE(n) "cat r:-,"#n
#define CMD_CLAST_SCSAMPLE(s,c) "cat r:l,"#s",l,"#c
#define CMD_PRINTLN "println"
#define CMD_UPLOAD "upload"
#define CMD_FSIZE "fsize"
#define CMD_UPLOAD_TO_SEC(sz) (2+((1*sz)/1000))
#define CMD_UPLOAD_Q "upload q"
#define CMD_UPLOAD_QB "upload q b"
#define CMD_SCR_LOAD "scr load"
#define CMD_SCR_RUN "scr run"
#define CMD_SCR_STAT "scr stat"
#define CMD_SCR_UNLOAD "scr unload"
#define CMD_MKCMD(fmt,...) ( (memset(g_cwg_cmdbuf,0,CWG_CMD_BUF_BYTES)!=NULL) && snprintf(g_cwg_cmdbuf,(CWG_CMD_BUF_BYTES-1),fmt,__VA_ARGS__)>0 ? g_cwg_cmdbuf : NULL)
#define CMD_LEN strlen(g_cwg_cmdbuf)
#define CWG_CLI_WRITE(p,s) ((NULL!=p && NULL!=s && NULL!=p->ser_io && p->ser_io->fd>0) ? write(p->ser_io->fd,s,strlen(s)) : -1)
#define CWG_TEST_SET(f,c,i) (f |= ( (c) ? (0<<i) : (1<<i) ) )

/////////////////////////
// Type Definitions
/////////////////////////


/////////////////////////
// Exports
/////////////////////////

#ifdef __cplusplus
extern "C" {
#endif
    extern char *g_cwg_cmdbuf;

    /// @fn uint32_t cwg_upload_file(cwg_ser_t *self, char *src)
    /// @brief upload file from host to controller
    /// @param[in] self instance
    /// @param[in] dest destination file name
    /// @param[in] src  source file name
    /// @param[in] binary true if binary, text otherwise
    /// @return bytes uploaded
    uint32_t cwg_upload_file(wser_t *self, char *dest, char *src, bool binary);

    /// @fn uint32_t cwg_download_file(cwg_ser_t *self, char *src)
    /// @brief download file from controller to host
    /// @param[in] self instance
    /// @param[in] dest destination file name
    /// @param[in] src  source file name
    /// @param[in] binary true if binary, text otherwise
    uint32_t cwg_download_file(wser_t *self, char *dest, char *src, bool binary);

    /// @fn uint32_t cwg_fget_lastn(cwg_ser_t *self, char *dest, char *src, char *ofmt)
    /// @brief get last n samples to file
    /// @param[in] self instance
    /// @param[in] dest destination file name
    /// @param[in] src  source file name (NULL for current)
    /// @param[in] ofmt format string
    uint32_t cwg_fget_lastn(wser_t *self, char *dest, int mode, char *src, uint32_t count, char *ofmt);

    /// @fn uint32_t cwg_mget_n(cwg_ser_t *self, byte *dest, uint32_t len, char *src, uint32_t count, char *ofmt)
    /// @brief get last n records to buffer
    /// @param[in] self instance
    /// @param[in] dest destination file name
    /// @param[in] len destination buffer length (bytes)
    /// @param[in] src  source file name (NULL for current)
    /// @param[in] count number of records
    /// @param[in] ofmt format string
    uint32_t cwg_mget_lastn(wser_t *self, byte *dest, uint32_t len, char *src, uint32_t count, char *ofmt);

    /// @fn uint32_t cwg_mcget_n(cwg_ser_t *self, byte *dest, uint32_t len, char *src, uint32_t count)
    /// @brief get last n CSV records to buffer
    /// @param[in] self instance
    /// @param[in] dest destination file name
    /// @param[in] len destination buffer length (bytes)
    /// @param[in] src  source file name (NULL for current)
    /// @param[in] count number of records
    uint32_t cwg_mcget_lastn(wser_t *self, byte *dest, uint32_t len, char *src, uint32_t count);

    /// @fn uint32_t cwg_fcget_lastn(cwg_ser_t *self, char *dest, char *src)
    /// @brief get last n CSV records to file
    /// @param[in] self instance
    /// @param[in] dest destination file name
    /// @param[in] src  source file name (NULL for current)
    uint32_t cwg_fcget_lastn(wser_t *self, char *dest, int mode, char *src, uint32_t count);

    /// @fn uint32_t cwg_fget_n(wser_t *self, char *dest, int mode, char *src, uint32_t start, uint32_t count, char *ofmt)
    /// @brief get n records to file (start at specified record)
    /// @param[in] self instance
    /// @param[in] dest destination file name
    /// @param[in] mode file open/create mode (see iowfile.h)
    /// @param[in] src  source file name (NULL for current)
    /// @param[in] start starting record (zero-indexed)
    /// @param[in] count number of records
    /// @param[in] ofmt format string
    uint32_t cwg_fget_n(wser_t *self, char *dest, int mode, char *src, uint32_t start, uint32_t count, char *ofmt);

    /// @fn uint32_t cwg_mget_n(cwg_ser_t *self, byte *dest, uint32_t len, char *src, uint32_t start, uint32_t count, char *ofmt)
    /// @brief get n records to buffer (start at specified record)
    /// @param[in] self instance
    /// @param[in] dest destination file name
    /// @param[in] len destination buffer length (bytes)
    /// @param[in] src  source file name (NULL for current)
    /// @param[in] start starting record (zero-indexed)
    /// @param[in] count number of records
    /// @param[in] ofmt format string
    uint32_t cwg_mget_n(wser_t *self, byte *dest, uint32_t len, char *src, uint32_t start, uint32_t count, char *ofmt);

    /// @fn uint32_t cwg_mcget_n(cwg_ser_t *self, byte *dest, uint32_t len, char *src, uint32_t start, uint32_t count)
    /// @brief get n records to buffer (start at specified record)
    /// @param[in] self instance
    /// @param[in] dest destination file name
    /// @param[in] len destination buffer length (bytes)
    /// @param[in] src  source file name (NULL for current)
    /// @param[in] start starting record (zero-indexed)
    /// @param[in] count number of records
    /// @param[in] ofmt format string
    uint32_t cwg_mcget_n(wser_t *self, byte *dest, uint32_t len, char *src, uint32_t start, uint32_t count);

    /// @fn uint32_t cwg_fcget_n(wser_t *self, char *dest, int mode, char *src, uint32_t start, uint32_t count)
    /// @brief get n records to file (start at specified record)
    /// @param[in] self instance
    /// @param[in] dest destination file name
    /// @param[in] mode file open/create mode (see iowfile.h)
    /// @param[in] src  source file name (NULL for current)
    /// @param[in] start starting record (zero-indexed)
    /// @param[in] count number of records
    /// @param[in] ofmt format string
    uint32_t cwg_fcget_n(wser_t *self, char *dest, int mode, char *src, uint32_t start, uint32_t count);


#ifdef __cplusplus
}
#endif

#endif // THIS_FILE
