#!/usr/bin/python

"""
    This module contains the deployment script to flash the BIOS in WinPE
"""

import string, os, os.path, shutil, sys, popen2, systemMgr
from logMgr import addLogRecord,CRITICAL,ERROR,WARNING,INFO,DEBUG
from config import DeploymentStore, DeployPath
from deploymentData import ATSTATE,FAILURE,UPDATE,REFRESH,REBOOT,UNSUPPORTED,UPDATEBIOS
import time
try:
    __file__
except:
    __file__ = __name__


def checkState(restore=0):
    """
        checkState() returns ATSTATE if at desired state
        checkState() returns FAILURE if state can't be achieved
        checkState() returns REBOOT if system reboot is needed once flashed
    """
    if not sys.platform == 'win32':
        print 'iFlash is intended for WinPE systems only'
        addLogRecord(0,__file__, INFO,'iFlash is intended for WinPE systems only')
        return FAILURE
    ret, build = systemMgr.queryProperty(0,'IntelBIOSID','BuildID','',{})
    if not build or ret:
        print 'Intel BIOS build unavailable: ret = %d'%ret
        addLogRecord(0,__file__, ERROR,'Intel BIOS build unavailable: ret = %d'%ret)
        return FAILURE
    from flash import getChassisSpec
    chassis, chassisSpec = getChassisSpec(restore)
    if not chassisSpec:
        return FAILURE
    updateVersion = chassisSpec[0]
    if build == updateVersion:
        print 'BIOS at correct version(%s)'%(build)
        addLogRecord(0,__file__, INFO,'BIOS at correct version(%s)'%(build))
        return ATSTATE
    return REBOOT

def iFlashUpdate(restore=0):
    state = checkState(restore)
    if state < UPDATE:
        return state
    ret, system = systemMgr.queryProperty(0,'IntelBIOSID','BoardFamilyID','',{})
    if not system or ret:
        print 'Intel board family unavailable: ret = %d'%ret
        addLogRecord(0,__file__, ERROR,'Intel board family unavailable: ret = %d'%ret)
        return FAILURE
    from flash import extractUpdate,getChassisSpec
    chassis, chassisSpec = getChassisSpec(restore)
    if not chassisSpec:
        return FAILURE
    filePath = extractUpdate(restore)
    if not filePath:
        return FAILURE
    if system == 'S3000':
        BIOSfile = os.path.join(filePath,'AH860%s.cap'%chassisSpec[UPDATEBIOS][-2:])
    else:
        BIOSfile = os.path.join(filePath,'R%s.CAP'%chassisSpec[UPDATEBIOS])
    
    print "running an example of flashing BIOS using iflash ..."
    
    from config import getstatusoutput
    flashdir = os.path.join(DeployPath,'win32','iFlash')
    cwd = os.getcwd()
    os.chdir(flashdir)
    #os.system("win2kinstall %s *INT0800 > nul"%os.path.join(flashdir,'flashud.inf'))
    status, output = getstatusoutput("iflash32 /ni /u %s"%BIOSfile)
    #os.system("win2kuninstall *INT0800 > nul")
    os.chdir(cwd)
    if status:
        print 'iflash32 failed: status = 0x%x, %s'%(status,output)
        addLogRecord(0,__file__, ERROR,'iflash32 failed: status = 0x%x, %s'%(status,output))
        return FAILURE
    else:
        print 'iflash32 BIOS update succeeded'
        addLogRecord(0,__file__, INFO,'iflash32 BIOS update succeeded')
    return REBOOT

if __name__ == '__main__':
    """
    this script assumed these enviroment variables have been set:
    (see deploy.sh or deploy.cmd)
        DeployPath
        DeploymentStore
        PATH
        LD_LIBRARY_PATH (Linux)
        PYTHONPATH
    and this script has been run:
        prepareDeployment
    """
    if len(sys.argv) == 1:
        restore = 0
    elif len(sys.argv) == 2 and sys.argv[1] == '0':
        restore = 0
    else:
        restore = 1
    state = checkState(restore)
    if state < UPDATE:
        sys.exit(state)
    state = iFlashUpdate(restore)
    if state == REBOOT:
        print "System must be reset to complete flash"
    sys.exit(state)
