/** \file
 *
 *  Contains the DataReceiver class declaration.
 *
 *  Copyright (c) 2007,2008,2009 MBARI
 *  MBARI Proprietary Information.  All Rights Reserved
 */

#ifndef DATARECEIVER_H_
#define DATARECEIVER_H_

class UniversalDataWriter;

#include "logger/Logger.h"

#include "../Lib/aes/AES.h"

/// Maximum consecuitive zeroes that may occur in a file
#define MAX_ZEROES 16

/// Defined to accommodate 9 byte header and 16 bytes of data in 255 byte packet
#define MAX_STREAM_CMD 130
#define MAX_TARGET 100

/**
 *  Handles data that is sent to the vehicle.
 *  Assumes that data that starts with a valid ASCII character is a command.
 *  Otherwise binary.
 *
 *  \ingroup supervisor
 */
class DataReceiver
{
public:

    enum BinaryTransferFlags
    {
        FILE_START         = 0x00, // Contains stamp, crc, size, streamCmd, target, data
        FILE_PART          = 0x01, // Contains stamp, offset, data
        FILE_MEDIUM_OFFSET = 0x02, // file offsets > 2^16 bytes
        FILE_LARGE_OFFSET  = 0x04, // file offsets > 2^24 bytes
        FILE_FLAG          = 0x80, // this is a file transfer
    };

    // Returns false after logging an error if an error occurs, otherwise returns true.
    static bool ReceiveSbd( const char* data, size_t dataLen, const char* keyText, Logger& logger );

    // Returns an error message if error occurs, otherwise returns empty string
    static Str TryReceiveSbd( const char* data, size_t dataLen, const char* keyText, Logger& logger );

    static void Receive( const char* data, size_t dataLen, Logger& logger );

protected:

    /// Write data to start of file, and set informational parameters
    /// Data contains stamp, size, path, data
    /// Sets streamCmd
    static void FileStart( const char* data, size_t dataLen,
                           unsigned int flags, unsigned int stamp,
                           char* infoFilename, char* partFilename,
                           unsigned int& crc, size_t& size,
                           char* streamCmd, char* targetPath,
                           Logger& logger );

    /// Write data to middle of file
    /// Data contains stamp, offset, data
    /// Sets streamCmd if possible
    /// Returns true if file CAN BE COMPLETE
    static void FilePart( const char* data, size_t dataLen,
                          unsigned int flags, unsigned int stamp,
                          char* infoFilename, char* partFilename,
                          unsigned int& crc, size_t& size,
                          char* streamCmd, char* targetPath,
                          Logger& logger );

    /// Returns true if file is completely written and there are no long
    /// stringstrailZ of zeroes in the data
    static bool FileDone( char* partFilename, unsigned int crc,
                          size_t size, char* targetPath,
                          Logger& logger );

private:

    /// Private constructor for singleton class
    DataReceiver();

    static AES Crypt_;
};

#endif /*DATARECEIVER_H_*/
