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

#include "MostRecentLogWriter.h"

#include "io/OutStream.h"
#include "logger/DataEntry.h"
#include "logger/SyslogEntry.h"

/// Constructor
MostRecentLogWriter::MostRecentLogWriter( LogWriter& outputTo )
    : DecimationLogWriter( outputTo, DecimationLogWriter::MOST_RECENT ),
      dataValue_( NULL )
{
    wipe();
}

// Destructor
MostRecentLogWriter::~MostRecentLogWriter()
{}

/// Write the log header, if any
unsigned int MostRecentLogWriter::writeHeader()
{
    unsigned int bytesSent( 0 );
    bytesSent += outputTo_.writeHeader();
    wroteHeader_ = true;
    return bytesSent;
}

void MostRecentLogWriter::wipe()
{
    timestamp_ = Timestamp::NOT_SET_TIME;
    unit_ = NULL;
    type_ = LogEntry::NOT_LOG_ENTRY;
    dataAccess_ = NULL;
    if( NULL != dataValue_ )
    {
        delete dataValue_;
        dataValue_ = NULL;
    }
    best_ = false;
    message_ = Str::EMPTY_STR;
    severity_ = Syslog::NONE;
    loggerFacility_ = NULL;
}

/// Write the given LogEntry - should lock the writeMutex_
unsigned int MostRecentLogWriter::write( const LogEntry* entry, const Unit* unit )
{
    MutexLocker lock( MostRecentLogWriterMutex_ );
    wipe();

    timestamp_ = entry->getTimestamp();
    unit_ = unit;
    type_ = entry->getType();

    const DataEntry* dataEntry;
    const SyslogEntry* syslogEntry;

    switch( type_ )
    {
    case LogEntry::DATA_LOG_ENTRY:
        dataEntry = static_cast<const DataEntry*>( entry );
        dataAccess_ = dataEntry->getDataAccess();
        dataValue_ = dataEntry->getDataValue()->copy();
        best_ = dataEntry->isBest();
        break;
    case LogEntry::SYSLOG_LOG_ENTRY:
        syslogEntry = static_cast<const SyslogEntry*>( entry );
        message_ = syslogEntry->getMessage();
        severity_ = syslogEntry->getSeverity();
        loggerFacility_ = &syslogEntry->getLoggerFacility();
        break;
    default:
        break;
    }
    return 0;
}

/// Do what needs to be done at the end of the cycle.
void MostRecentLogWriter::endCycle()
{
    outputTo_.endCycle();
}

/// Write the log footer, if any
unsigned int MostRecentLogWriter::writeFooter()
{
    MutexLocker lock( MostRecentLogWriterMutex_ );
    unsigned int bytesSent( 0 );
    LogEntry* logEntry( NULL );
    switch( type_ )
    {
    case LogEntry::DATA_LOG_ENTRY:
        logEntry = new DataEntry( dataAccess_, dataValue_->copy(), timestamp_, best_, true );
        outputTo_.write( logEntry, unit_ );
        break;
    case LogEntry::SYSLOG_LOG_ENTRY:
        logEntry = new SyslogEntry( message_, severity_, *loggerFacility_, timestamp_ );
        outputTo_.write( logEntry );
        break;
    default:
        break;
    }
    if( NULL != logEntry )
    {
        delete logEntry;
    }
    wipe();
    return bytesSent;
}
