#!/usr/bin/env python3
# Copyright (c) 2006-2010 Arista Networks, Inc.  All rights reserved.
# Arista Networks, Inc. Confidential and Proprietary.

# This program handles CLI show command pipes redirecting to local files.
#
# Usage: redirect [--append] [--tee] [filename urlname]
#
# The purpose of this program is to isolate IOError due to redirection
# from the CLI itself.
#
# Returns error if there is any error in the file operation.

import sys, optparse, signal, errno # pylint: disable=deprecated-module

op = optparse.OptionParser(
   usage="""usage: %prog [OPTIONS] FILENAME URL
""")
op.add_option( "", "--append", action="store_true",
               help="append to file instead of overwrite" )
op.add_option( "", "--tee", action="store_true", dest="stdout",
               help="print to stdout" )

opts, args = op.parse_args( sys.argv[ 1: ] )

if args and len( args ) != 2:
   op.print_help()
   sys.exit( 1 )

fileError = False
stdoutError = False
fout = None

# let SIGPIPE kill us
signal.signal( signal.SIGPIPE, signal.SIG_DFL )

def handleFileError( err ):
   global fileError
   # pylint: disable-next=consider-using-f-string
   fileError = "% Error redirecting output to {} ({})".format(
      args[ 1 ], err.strerror )
   if not opts.stdout:
      # for tee, we should continue to print to stdout
      print( fileError )
      sys.exit( 1 )

if len( args ) == 2:
   try:
      # pylint: disable-next=consider-using-with
      fout = open( args[ 0 ], 'a' if opts.append else 'w' )
   except OSError as e:
      handleFileError( e )

try:
   for line in sys.stdin:
      if fout and not fileError:
         try:
            fout.write( line )
         except OSError as e:
            handleFileError( e )

      if opts.stdout and not stdoutError:
         try:
            sys.stdout.write( line )
         except OSError as e:
            stdoutError = True
            if e.errno != errno.EPIPE:
               raise
            # This is most likely caused by user interruption (e.g.,
            # pressing 'q' in 'less'). We exit here, although it's
            # likely we have not finished writing to fout.
            break

   if fout and not fileError:
      try:
         fout.close()
      except OSError as e:
         handleFileError( e )

   if opts.stdout and not stdoutError:
      try:
         sys.stdout.flush()
      except OSError as e:
         if e.errno != errno.EPIPE:
            raise
except KeyboardInterrupt:
   sys.exit( 1 )

if fileError:
   print( fileError )
   sys.exit( 1 )

sys.exit( 0 )
