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

import EosCloudInitLib as ecil
import AwsCloudInit as awsci
import AzureCloudInit as azureci
import GcpCloudInit as gcpci
import KvmInit as kvmi
import OpenstackCloudInit as oci
import os
import sys
import VeosHypervisor
import Tac

CN10K_DIRS = [ '/usr/lib64/cn10k', '/usr/share/dpdk/tools/cn10k', ]

def dpsIntfUpgradeRequired():
   if VeosHypervisor.platformBareMetal():
      # Platform doesn't support DPS
      return False
   if VeosHypervisor.platformCeosR():
      # Platform doesn't support DPS
      return False
   if VeosHypervisor.platformCaravan():
      # Platform shipped with DpsIntf, never had Ethernet100
      return False
   return True

def isDiagnosticsMode():
   with open( "/proc/cmdline" ) as f:
      cmdline = f.read()
      return 'AristaDiagnosticsMode=NoEOS' in cmdline

def setupCn10kLib( cn10kFile ):
   # Replace generic ARM libraries with cn10k
   # on supported platforms
   genericFile = cn10kFile.replace( "/cn10k", "" )
   if ( not os.path.exists( genericFile ) or
        not os.path.exists( cn10kFile ) ):
      return

   try:
      Tac.run( [ 'mv', genericFile,
                 f'{genericFile}.generic' ], asRoot=True )
      Tac.run( [ 'ln', '-s', cn10kFile,
                 genericFile ], asRoot=True )
   except Tac.SystemCommandError as e:
      print( f"Failed to setup CN10k environment: {e.output}",
             file=sys.stderr )

if __name__ == '__main__':
   # Skip EosCloudInit if we are running in diagnostics mode
   if isDiagnosticsMode():
      sys.exit( 0 )

   doCleanup = True
   platform = VeosHypervisor.getPlatform()
   if platform == 'AWS':
      awsci.cloudInit()
   elif platform == 'Azure':
      azureci.cloudInit()
   elif platform == 'GCP':
      gcpci.cloudInit()
   elif platform == 'KVM':
      kvmi.cloudInit()
   elif platform == 'Openstack':
      oci.cloudInit()
   else:
      print( "Skipping CloudInit" )
      doCleanup = False

   if not ecil.isSupportedCloudEOSPlatform():
      # system should halt now
      print( "Unsupported CloudEOS platform" )

   # In case the EosCloudInit script has to exit without invoking the dhclient, make
   # sure we don't crash while trying to read the dhclientPidFile in cleanupExit()
   if not os.path.exists( ecil.dhclientPidFile ):
      os.mknod( ecil.dhclientPidFile )

   if ecil.isModeSfe():
      if dpsIntfUpgradeRequired():
         print( "Run DpsIntfUpgrade" )
         ecil.ethernet100ToDpsIntfUpgrade()

      if platform == 'Marvell Octeon10 DPU':
         print( "Setup Sfe CN10K environment" )

         for cdir in CN10K_DIRS:
            # Setup Sfe cn10k environment
            if not os.path.isdir( cdir ):
               continue
            for lib in os.listdir( cdir ) :
               setupCn10kLib( os.path.join( cdir, lib ) )

      # if kernel parameters in cmdline are correct
      # then setupSfeKernelParams() will return false
      # and dut will not reboot
      if ecil.setupSfeKernelParams():
         print( "Kernel command line params changed. Rebooting system" )
         os.system( "/sbin/reboot" )
      # create fabric device
      if not ecil.fabricDevicePresent():
         ecil.createFabricDevice()


   if doCleanup:
      ecil.cleanupExit( "CloudInit done !" )
