# Copyright (c) 2014, Neville-Neil Consulting
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# Neither the name of Neville-Neil Consulting nor the names of its 
# contributors may be used to endorse or promote products derived from 
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Author: George V. Neville-Neil
#
# Description: A set of libraries to process NTP peer and loopstat
# files.  Used by various command line tools in this directory.
#

require(zoo) # Time series objects

# Functions for working with NTP log output

# @file - A properly formatted NTP loop file generated by the daemon
#
# Returns: The raw data frame, merged timeseries (offset, delay, m->s, s->)
#          offset time series, delay time series,
#          master.to.slave time series, and slave.to.master time series
#
ntpLoopRead <- function(file) {

    # Attempt to read log files from version 2.3 first.
    data = read.table(file, fill=TRUE, sep=" ",
        col.names=c("day", "second", "offset", "drift", "error", "stability", "interval"),
        blank.lines.skip=TRUE, header=FALSE, skip=100)

    offset = zoo(data$offset, data$second)
    drift = zoo(data$drift, data$second)
    stability = zoo(data$stability, data$second)
    ts = merge(offset, drift, stability)

    return (list(data=data, ts=ts, offset=offset, drift=drift,
                 stability=stability))
}

# @file - A properly formatted NTP peer file generated by the daemon
#
# Returns: The raw data frame, merged timeseries (offset, drift, error)
#
ntpPeerRead <- function(file) {

    # Attempt to read log files from version 2.3 first.
    data = read.table(file, fill=TRUE, sep=" ",
        col.names=c("day", "second", "address", "status", "offset", "delay", "dispersion", "skew"),
        blank.lines.skip=TRUE, header=FALSE, skip=100)

    offset = zoo(data$offset, data$second)
    delay = zoo(data$delay, data$second)
    dispersion = zoo(data$dispersion, data$second)
    ts = merge(offset, delay, dispersion)

    return (list(data=data, ts=ts, offset=offset, delay=delay,
                 dispersion=dispersion))
}

#
# Graphs a dataframe returned by a call to ntpPeer/LogRead
#
# @logframe - A data frame returned by ptpLogRead
# @value - Graph only a specific value rather than the four major ones.
# @output - An optional file name to place a PNG of the graph into
#
ntpGraph <- function(logframe, value, start, end, output) {

  if (!missing(output))
    png(filename=output, height=960, width=1280, bg="white")

  if (!missing(start))
    logframe = logframe[index(logframe) > as.POSIXct(start)]
  if (!missing(end))
    logframe = logframe[index(logframe) < as.POSIXct(end)]
  if (!missing(start) && !missing(end))
    logframe = logframe[index(logframe) > as.POSIXct(start) &
      index(logframe) < as.POSIXct(end)]
  plot(logframe, type="p", cex=.1, main="NTP Log Graph", xlab="Time", mar=c(1, 5.1, 1, 5.1))
  if (!missing(output))
      dev.off()
  return(NULL)

}
    
#
# Draw a simple histogram of some one variable in our log
#
# e.g. foo$log$offset etc.

ntpHistogram <- function(log, start, end, output) {
    if (!missing(output))
        png(filename=output, height=960, width=1280, bg="white")
    if (!missing(start))
        log = log[index(log) > as.POSIXct(start)]
    if (!missing(end))
        log = log[index(log) < as.POSIXct(end)]
    if (!missing(start) && !missing(end))
        log = log[index(log) > as.POSIXct(start) &
            index(log) < as.POSIXct(end)]
    left = min(log)
    right = max(log)
    height = max(length(log)) * 0.69
    hist (log, xlim=c(left, right), ylim=c(0,height), breaks=20,
          col=rgb(1.0, 0, 0, 0.5))
    if (!missing(output))
        dev.off()
}

