#ifndef __Log_h__
#define __Log_h__

#include "File.h"
#include "LogListener.h"
#include <mutex>
#include <string>
#include <sstream>

namespace coreutils {
   
   class ConsoleServer;
   
   static const int LOG_NONE = 0;
   static const int LOG_INFO = 1;
   static const int LOG_WARN = 2;
   static const int LOG_EXCEPT = 4;
   static const int LOG_DEBUG_1 = 8;
   static const int LOG_DEBUG_2 = 16;
   static const int LOG_DEBUG_3 = 32;
   static const int LOG_DEBUG_4 = 64;
   
   ///
   /// Log
   ///
   /// Provides easy to access and use logging features to maintain a
   /// history of activity and provide information for activity debugging.
   ///
   
   class Log : public std::ostringstream {
      
    public:
      
      ///
      /// Constructor method that accepts a pointer to a log listener
      /// This enables the Log object to send new log
      /// messages to the connected listener.
      ///
      /// @param consoleServer a pointer to the console server that will 
      /// be used to echo log entries.
      ///
      
      Log(LogListener *logListener);  
      
      ///
      /// Constructor method accepts a file object that will be used to
      /// echo all log entries. This provides a permanent disk file record
      /// of all logged activity.
      ///
      
      Log(File *logFile);
      
      ///
      /// Constructor method that is used to send a message to the log. 
      ///
      /// @param level the logging level to associate with this message.
      ///
      /// To send log message: Log(LOG_INFO) << "This is a log message.";
      ///
      
      Log(int level);
      
      ///
      /// The destructor for the log object.
      ///
      
      ~Log();
      
      bool output = false;
      
      ///
      /// Set the logListener to point to the instantiated LogListener
      /// object for the application.
      ///
      
      static LogListener *logListener;
      
      ///
      /// Specify a File object where the log entries will be written as
      /// a permanent record to disk. 
      ///
      
      static File *logFile;
      
      ///
      /// A meaningless sequenctial number that starts from 0 at the 
      /// beginning of the logging process.
      ///
      
      static int seq;

    private:
      std::mutex mtx;
      
   };
   
}

#endif
