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

from __future__ import absolute_import, division, print_function
import six
import Plugins, Tac, optparse, sys # pylint: disable=deprecated-module
import GenprefdlLib
import traceback
   
### Executable code section ################################

parser = optparse.OptionParser( prog='genprefdl', usage='''
   %prog -- Fetches and formats prefdl from NVM.

   %prog [ --prefdl <encoded prefdl> ] [ --mfg ]
      ''' )

parser.add_option( "-p", "--prefdl", action="store",
                   help="Base prefdl string (encoded)." )
parser.add_option( "--platform", action="store", default=None,
                   help="Specify a platform to perform prefdl read from." )
parser.add_option( "-m", "--mfg", action="store_true", default=False,
                   help="Used by manufacturing. Reads all IDPROMs in the system." )
parser.add_option( "--plugin", action="append", default=None, dest="plugins",
                   help="Specify a GenprefdlPlugin plugin to load. Can be used"
                   " multiple times to create a list of plugins to load." )

( options, args ) = parser.parse_args()

prefdl = b""
# If specified, read and decode base system prefdl from args.
if options.prefdl:
   prefdl = Tac.run( [ "/bin/sh", "-c", "/bin/echo \"" + options.prefdl + \
                  "\" |  prefdl --decode -" ], stdout=Tac.CAPTURE, text=False )

# Instantiate genprefdlPluginContext
pluginContext = GenprefdlLib.genprefdlPluginContext( options.platform )

# Load Genprefdl Plugins
Plugins.loadPlugins( "GenprefdlPlugin", context=pluginContext,
                     plugins=options.plugins )

# Validate cpu prefdl reader existence
if not pluginContext.prefdlReader:
   print("genprefdl: Platform specific reader not registered. " + \
                        "Install GenprefdlPlugin.", file=sys.stderr)
   sys.exit( 1 )

# Read prefdl
# Note: Since this points to a function, but is not assigned in this
# scope, pylint throws E1102. It is however assigned by plugins.
try:
   prefdl += pluginContext.prefdlReader() # pylint: disable-msg=E1102
except KeyboardInterrupt:
   sys.exit( 0 )
except: # pylint: disable-msg=W0702
   tb = sys.exc_info()[ 2 ]
   traceback.print_tb( tb )
   traceback.print_exc()
   raise

# Validate prefdl
assert prefdl, "prefdl read incorrectly. Verify GenprefdlPlugin."

# Extract SID
sid = GenprefdlLib.getSidFromPrefdl( prefdl )

if sid and options.mfg:
   # Read all mfg prefdls
   for reader in pluginContext.mfgPrefdlReader:
      prefdl += reader( sid )

# Validate MAC address existence.
GenprefdlLib.validateMacInPrefdl( prefdl )

if six.PY2:
   sys.stdout.write( prefdl )
else:
   sys.stdout.buffer.write( prefdl ) # pylint: disable=no-member
