######################### rover_utils.rb achase@mbari.org ###################### 
#
# Common utilities
#
################################################################################

# A module for standardized logging

require "singleton"

########################################################################
# LogDir - Attempts to manage log directories for missions and tests
# while allowing classes to continue to use LogHelper as a mixin
# ######################################################################
class LogDir
  include Singleton

  # These are the directories that LogHelper uses to locate data and
  # log files
  attr_accessor :datalog_dir, :syslog_dir, :eventlog_dir, :mst,
                :backlog_dir
  
  def initialize
    # Point the "latest" sym link to the testlogs directory as
    # default data and log location.
    # These strings should eventually come from a config object
    # 
    symname = "/cf/rover/logs/latest"
    File.unlink(symname) if File.exist?(symname)
    File.symlink("/cf/rover/logs/testlogs", symname)

    @datalog_dir = '/cf/rover/logs/latest/'
    @syslog_dir = '/cf/rover/logs/latest/'
    @backlog_dir = '/backup/testlogs/'

    @mst = Time.now.gmtime
    puts @mst

  end
    
  # Create a uniquely named directory for mission log files. This method
  # is supposed to be invoked at the start of a mission.
  #
  # home - string: the top level logs directory name (i.e., "/cf/rover/logs")
  # prefix - string: optional prefix for the directory name (i.e., "tanktest")
  #
  # If successful, a uniquely-named directory will be created in home
  # directory. A ".n" will be appended to the prefix to make a unique name,
  # where 'n' are successive integers beginning with zero.
  #
  def newlogdir(home, prefix=nil)

    # Create a new log dir in the home directory. Perhaps the home
    # directory should come from a configuration object.
    #
    # First ensure that the home directory exists
    #
    return false if (File.exists?(home) == false ||
                     File.stat(home).directory? == false)

    # Define a log directory prefix if necessary using today's date
    #
    if (prefix == nil)
      today = Time.now #Date.today
      mzero = ""
      mzero = "0" if today.month < 10  # leading zero?
      dzero = ""
      dzero = "0" if today.day < 10    # leading zero?

      prefix = today.year.to_s + "." + mzero + today.month.to_s + "." +
               dzero + today.day.to_s
    end

    # Create a unique directory name using the home directory and the prefix
    #
    ii = 0
    while true
      dirname = home + "/" + prefix + "." + ii.to_s
      if false == File.exist?(dirname)
        break
      end
      ii += 1
    end

    dirname = dirname + "/"
    Dir.mkdir(dirname)  # should catch possible exception here

    # Point the "latest" sym link to the testlogs directory
    #
    symname = "/cf/rover/logs/latest"
    File.unlink(symname) if File.exist?(symname)
    File.symlink(dirname, symname)
        
    @datalog_dir = dirname
    @syslog_dir = dirname
    @syslogname = nil
    @eventlog_dir = dirname
    @eventlogname = nil

    true
  end
end

module LogHelper

  # Removed postfix, added filename as optional parameter.
  # If no filename is given, we use the default filename using the class name.
  # Changed the format of the timestamp, and now commas delimit fields in a record.
  # Timestamp includes more precision.
  # 
  def datalog msg, filename=nil
    filename = t.strftime("#{self.class.name}%Y%m%d.dat") if !filename
    logfilename = LogDir.instance.datalog_dir + filename
    t = Time.now
    t.gmtime
    hh = t.usec.to_s
    elapsed = t.to_f - LogDir.instance.mst.to_f
    File.open(logfilename, "a") do |file|
      file.puts t.strftime("%Y%m%d%H%M%S.#{hh[0..1]}, ") << elapsed.to_s <<
                ", " << msg
    end 
  end
  
  # Write string to data file without a timestamp. Intended for header info.
  # 
  def datawrite(string, filename=nil)
    t = Time.now
    t.gmtime
    filename = t.strftime("#{self.class.name}%Y%m%d.dat") if !filename
    logfilename = LogDir.instance.datalog_dir + filename
    File.open(logfilename, "a") do |file|
      file.puts string
    end 
  end
  
  # Syslog file is based on mission not the date
  # 
  def syslog message
    @syslogname = LogDir.instance.syslog_dir + "syslog" unless @syslogname
    t = Time.now
    elapsed = t.to_f - LogDir.instance.mst.to_f
    File.open(@syslogname, "a") do |file|
      file.puts t.strftime("%m-%d/%H:%M:%S ") << elapsed.to_s <<
                ": #{self.class.name}: " << message
    end
  end

  # Eventlog file is based on mission not the date
  # 
  def eventlog message
    syslog message
    @eventlogname = LogDir.instance.eventlog_dir + "eventlog" unless @eventlogname
    t = Time.now
    elapsed = t.to_f - LogDir.instance.mst.to_f
    File.open(@eventlogname, "a") do |file|
      file.puts t.strftime("%m-%d/%H:%M:%S ") << elapsed.to_s <<
                ": #{self.class.name}: " << message
    end
  end

  def LogHelper.syslog message
    t = Time.now
    logfilename = LogDir.instance.syslog_dir + "syslog"
    File.open(logfilename, "a") do |file|
      file.puts t.to_s << ": " << message
    end
  end

end

