#!/usr/bin/env python
# Copyright (c) 2012 Arista Networks, Inc.  All rights reserved.
# Arista Networks, Inc. Confidential and Proprietary.

import errno
import optparse
import sys
import time
import EosLogUtil

usage = r"""

   %prog -- Dumps EOS log files

   %prog COMMAND -l|--logdir LOGDIR [-f|--file SAVEFILE] [-m|--match REGEX]
                 [-r|--runId RUNID] [-z|--maxsize MAXSIZE] [-n|--no-header]

   COMMAND:

   save: Save the current logfile information to stdout.

   dump: Dump the current logfile content. If a valid savefile is specified,
         it only dumps new content since the save, and updates the savefile
         with the new information.

   REGEX is a regular expression that is used to retrieve filenames
   that can be grouped together. The matched string is used as the name of
   the logfile, or you can use '?P<name>' to specify the name. For example,
   if there are the following files:

      eos, eos.1.gz, eos-console, eos-console.1.gz

   using "-m eos" would generate two files:

      eos (eos and eos.1.gz)
      eos-console (contains eos-console and eos-console1.gz)

   If you want to only match eos and eos.1.gz under one file 'eos', you can do

      -m '(?P<name>eos)($|\..*\.gz)'

   Alternatively you can also use lookahead:

      -m 'eos(?=($|\..*\.gz))'
"""

op = optparse.OptionParser( prog='FetchLogs', usage=usage )
op.add_option( '-l', '--logdir', action='store', help='log directory' )
op.add_option( '-f', '--file', action='store', help='save file' )
op.add_option( '-m', '--match', action='store',
               help='regex for matching names' )
op.add_option( '-r', '--runId', action='store', help='Record runId' )
op.add_option( '-z', '--maxsize', action='store', type=int,
               help='Max dump size for any file' )
op.add_option( '-n', '--no-header', action='store_true',
               help='Do not print header' )

opts, args = op.parse_args( )

if not args or len( args ) > 1:
   op.error( "Missing or extra command" )
if not opts.logdir:
   op.error( "Missing log directory" )

try:
   if args[ 0 ] == 'save':
      EosLogUtil.save( opts.logdir, opts.file, match=opts.match )
   elif args[ 0 ] == 'dump':
      files = EosLogUtil.dump( opts.logdir, opts.file,
                               match=opts.match, runId=opts.runId )
      # output by filename
      for name in sorted( files ):
         vfile = files[ name ]
         if not opts.no_header:
            mtime = time.localtime( vfile.mtime() )
            cursor = vfile.tell()
            header = [ '-' * 15, time.strftime( "%b %d %H:%M", mtime ), name ]
            if cursor:
               lastFetched = ""
               if cursor.runId:
                  lastFetched = ", last fetched by run %s" % cursor.runId
               header.append( '[offset %d:%d%s]' % ( len( cursor.inodes ) - 1,
                                                     cursor.currentFileSize,
                                                     lastFetched ) )
            header.append( '-' * 15 )
            print ' '.join( header )
         if opts.maxsize:
            print vfile.readTail( opts.maxsize )
         else:
            for x in vfile:
               sys.stdout.write( x )
            if not opts.no_header:
               # print an empty line only when it's no_header
               print
   else:
      op.error( "Invalid command" )
except KeyboardInterrupt:
   pass
except IOError, e:
   if e.errno == errno.EPIPE:
      exit()
   raise
