#!/bin/bash

#########################################
# Name:
#
# Summary:
#
# Description:
#
# Author:
#
# Copyright MBARI
#
#########################################

#########################################
# Script configuration defaults
# casual users should not need to change
# anything below this section
#########################################
X_ARG="defaultXValue"

#################################
# Script variable initialization
#################################
VERBOSE="FALSE"
let "SEG_SIZE=1024*1024"
#1024*1024"
let "SEG_COUNT=10"
let "LOG_SIZE=0"
LOG_FILE=""
let "LOG_SEG=0"
OVERWRITE="N"
let "CURRENT_SEG=0"
DO_HEADER="N"

#################################
# Function Definitions
#################################
#################################
# name: sigTrap
# description: signal trap callback
# will interrupt 
# args: none
#################################
sigTrap(){
    exit 0;
}

#################################
# name: printUsage
# description: print use message
# args: none
#################################
printUsage(){
    echo
    echo "usage: `basename $0`"
    echo "-s <seg_size>  : log segment size  [$SEG_SIZE]"
    echo "-c <seg_count> : log segment count [$SEG_COUNT]"
    echo "-f <file>      : log file          [$LOG_FILE]"
    echo "-O             : overwrite         [$OVERWRITE]"
    echo "-H             : write header      [$DO_HEADER]"
    echo "-V             : verbose output    [$VERBOSE]"
    echo "-h             : print help message"
    echo ""
    echo
}

########################################
# name: vout
# description: print verbose message to stderr
# args:
#     msg: message
########################################
vout(){
    if [ "$VERBOSE" == "TRUE" ]
    then
	echo "$1" >&2
    fi
}

########################################
# name: imsg
# description: echos with indent
# args:
#     msg: message
#  indent: indent level
########################################
imsg(){
  OIFS=$IFS
  IFS=""
  msg_pad="                                        "
  let "msg_indent=${1}"
  shift
  all="${@}"
  printf "%s%s\n" ${msg_pad:0:${msg_indent}} ${all}
  IFS=$OIFS
}

########################################
# name: msg
# description: echos with default indent
# args:
#     msg: message
########################################
msg(){
 imsg $MSG_INDENT "${*}"
}

########################################
# name: exitError
# description: print use message to stderr
# args:
#     msg:        error message
#     returnCode: exit status to return
########################################
exitError(){
    echo >&2
    echo "$1" >&2
    echo >&2
    exit $2
}

########################################
# name: rotate_file
# description: rotate log file
# args:
#     $1:        path to base log file
#     returnCode: exit status to return
########################################
rotate_file(){
	# check file size
	FILE_SIZE=$(stat -c %s ${1})
	
	# compare log file to max segment size
	if [ "${FILE_SIZE}" -ge "${SEG_SIZE}" ]
	then
		# if max size, time to rotate...
		vout "rotate ${1}: Y"
		
		# find the largest existing segment
		# [assumes that log segments are contiguous]
		i=1
		fpath=`dirname ${1}`
		fname=`basename ${1}`
		while [ -f "${fpath}/${fname}.${i}" ]
		do
			let "i+=1"
		done
		
		# if max seg count > 0
		# rotate over last segment
		# otherwise, will not limit number of 
		# log segments
		let "j=${i}"
		if [ "${SEG_COUNT}" -gt 0 ] && [ "${j}" -gt "${SEG_COUNT}" ]
		then
			let "j=${SEG_COUNT}"
		fi
		
		# bump log segments to next higher number 
		# starting with oldest
		while [ "${j}" -gt 1 ]
		do
			let "i=${j}-1"
			#echo "setting ${fpath}/${fname}.${i} to ${fpath}/${fname}.${j}"
			mv ${fpath}/${fname}.${i} ${fpath}/${fname}.${j}
			let "j-=1"			
		done
		# move current log segment 
		mv ${1} ${1}.1
		
		if [ "${DO_HEADER}" == "Y" ]
		then
			# optionally, write header
			HEADER=`date`
			echo "== ${HEADER} ==" >> ${1}	
		fi
	else	
		vout "rotate ${1}: N"
	fi
}

init_file(){

	if [ -f "${1}" ]
	then
		echo "file $1 exists: Y"
		rotate_file ${1}
	else
			if [ -e "${1}" ]
			then
				exitError "file $1 is not a regular file"
			else
				echo "file $1 exists: N"
			fi
	fi
}

##########################
# Script main entry point
##########################


# Argument processing
if [ "$#" -eq 0 ];then
    printUsage
    exit 0
fi

while getopts c:f:hHOs:V Option
do
    case $Option in
	c ) SEG_COUNT=${OPTARG}
	;;
	s ) SEG_SIZE=${OPTARG}
	;;
	f ) LOG_FILE=${OPTARG}
	;;
	H ) DO_HEADER="Y"
	;;
	O ) OVERWRITE="Y"
	;;
	V ) VERBOSE="TRUE"
	;;
	h)printUsage
	  exit 0
	;;
	*) exit 0 # getopts outputs error message
	;;
    esac
done

# call sigTrap on INT,TERM or EXIT
# trap sigTrap INT TERM EXIT

# reset trapped signals
# trap - INT TERM EXIT

init_file ${LOG_FILE}

vout "SEG_SIZE  :[$SEG_SIZE]"
vout "SEG_COUNT :[$SEG_COUNT]"
vout "LOG_FILE  :[$LOG_FILE]"
vout "OVERWRITE :[$OVERWRITE]"
vout "DO_HEADER :[$DO_HEADER]"

if [ -f "${LOG_FILE}" ]
then
	if  [ "${OVERWRITE}" != "Y" ]
	then
		exitError "File exists"
	fi
fi

# read line from stdin
while read line; do
	# write it to the log
	echo "${line}" >> $LOG_FILE
	# compute space remaining in current segment
	FILE_SIZE=$(stat -c %s $LOG_FILE)
	let "REMAINING=${SEG_SIZE}-${FILE_SIZE}"
	# if full, rotate log
	if [ ${REMAINING} -le 0 ]
	then
		rotate_file ${LOG_FILE}
	fi
done 
