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


#ifndef SYSLOGENTRY_H_
#define SYSLOGENTRY_H_

#include "utils/Str.h"
#include "utils/Mutex.h"

#include "LogEntry.h"
#include "Syslog.h"

/// A derived type of
///
/// \ingroup logging

class CodedStr;
class RingBufferVoid;

/**
 *  LogEntry with information specific to "Syslog"-like text
 *  logs. A Syslog::Severity value is associated with each text entry,
 *  indicating its importance.  Severities include:
 *  \li Syslog::NONE - Currently is ignored
 *  \li Syslog::DEBUG - Currently is logged to syslog text file only.
 *  \li Syslog::INFO - Currently is logged and shown on screen
 *  \li Syslog::ERROR - Currently is logged and shown on screen
 *  \li Syslog::IMPORTANT - Currently is logged, shown on screen, and sent via radio to shore
 *  \li Syslog::FAULT - Currently is logged, shown on screen, and sent via radio to shore
 *  \li Syslog::CRITICAL - Currently is logged, shown on screen, and sent via radio to shore
 *
 * A SyslogEntry is serialized as:
 * - a 16-bit header (serialized using OutStream::writeUShortCompact) including:
 * 	 \li 12 high bits: Actor code (which can be used to look up
 *       what code unit is writing to the log)
 *   \li 2 bits: Syslog::Severity code, indicating the severity of the message
 *       being logged: from debug messages to messages that must be relayed to
 *       shore via satellite.
 *   \li 2 bits: the value 2, indicating this is a SyslogEntry
 * - 64-bit Timespan as integer microseconds since the previous LogEntry,
 *   serialized using OutStream::writeLongLongCompact.
 * - 16-bit integer length of the character sequence that follows, serialized
 *   using OutStream::writeUShortCompact
 * - the characters of the message, with no termination character.
 *
 *  \ingroup logging
 */
class SyslogEntry : public LogEntry
{
public:
    /// Constructor, initialized from a Str.
    SyslogEntry( const Str &inMsg, Syslog::Severity sev, const CodedStr& loggerFacility,
                 const Timestamp& timestamp = Timestamp::NOT_SET_TIME,
                 const Service::ServiceType serviceType = Service::SERVICE_UNSPECIFIED );

    /// Copy Constructor
    SyslogEntry( const SyslogEntry& syslogEntry );

    /// Destructor
    virtual ~SyslogEntry();

    /// Override new
    void* operator new( size_t size );

    /// Override delete
    void operator delete( void* p );

    /** Read new SyslogEntry from a stream.
     *
     *  Implements requirement: \ref req_timing_accurateStorage
     *
     */
    static SyslogEntry* Read( Timestamp& timeBase, Timespan& timeAdjust, InStream &inStream, unsigned short firstWord, Logger& logger, bool& error );

    /** Send payload to a stream
     *
     *  Implements requirement: \ref req_timing_accurateStorage
     *
     */
    virtual unsigned int write( Timestamp& timeBase, OutStream& logStream ) const;

    // Convert payload to Str
    virtual Str toString( const Unit* unit = NULL ) const;

    // Convert payload to simple Str for inclusion in a Kml file.
    virtual Str toKmlString( const Unit* unit = NULL ) const;

    /// Get the message
    const Str &getMessage( void ) const
    {
        return message_;
    };

    /// Return the severity
    Syslog::Severity getSeverity( void ) const
    {
        return severity_;
    };

    const CodedStr& getLoggerFacility( void ) const
    {
        return loggerFacility_;
    }

private:

    /// The stored freetext message
    Str message_;
    Syslog::Severity severity_;
    const CodedStr& loggerFacility_;

    /// Declared as a pointer to avoid including RingBuffer.h header here.
    static RingBufferVoid* MallocRing_;

    /// Makes sure that mallocRing_s is deleted on shutdown
    class StaticDestructor
    {
    public:
        ~StaticDestructor();
    };

    /// Static instance of StaticDestructor
    static SyslogEntry::StaticDestructor StaticDestructor_;

    /// Used for free/delete operations
    static Mutex Mutex_;
};

#endif /*SYSLOGENTRY_H_*/
