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

#ifndef LOGGER_H_
#define LOGGER_H_

#include "component/FailureMode.h"
#include "logger/LoggerBase.h"
#include "logger/Syslog.h"
#include "Service.h"
#include "utils/CodedStr.h"
#include "utils/Timestamp.h"

class Component;
class DataAccessor;
class DataElement;
class LogEntry;

/**
 *  Client-side interface for injecting log data into the log queue.
 *  Injects data messages into a logging queue.  This queue is then
 *  processed asynchronous to the logger call.
 *
 *  \ingroup logging
 */
class Logger : public LoggerBase
{

    friend class Slate;

public:

    enum TimePrecisionType
    {
        TIME_PRECISION_MICROS,
        TIME_PRECISION_MILLIS
    };

    /// Constructor
    Logger( const char *facilityIn );

    /// Constructor
    Logger( const Str &facilityIn );

    /// Destructor
    virtual ~Logger();

    /// The generic "put this entry in the queue"
    void log( LogEntry *entry );

    /// Create a syslog entry, push into queue
    virtual void syslog( const Str& msg, Syslog::Severity sev = Syslog::DEBUG, Service::ServiceType serviceType = Service::SERVICE_UNSPECIFIED );

    using LoggerBase::syslog;

    /// Create a new EventEntry for setting a DataElement's accuracy
    void logSetAccuracy( Component* component, DataElement* dataElement );

    /// Create a new EventEntry for a Component load/unload
    void logComponentLoad( Component* component, const bool loaded );

    /// Create a new EventEntry for a (Mission)Component run
    void logComponentRun( Component* component, const short loop );

    /// Create a new EventEntry for a Component failure
    void logComponentFailure( Component* component,
                              const FailureMode::FailType failure, const int failCount );

    /// Create a new DataEntry
    void logData( DataAccessor& accessor, bool changed );

    static Timestamp& LastCriticalErrorReceived()
    {
        return CriticalErrorReceived_;
    }

private:

    /// Protected Constructor for use by Slate
    Logger( const CodedStr* facilityIn );

    static Timestamp CriticalErrorReceived_;

    friend class CBIT;

    static void ClearCrtiticalErrorReceived()
    {
        CriticalErrorReceived_ = Timestamp::NOT_SET_TIME;
    }
};

#endif /*LOGGER_H_*/
