#!/usr/bin/python

"""
This module contains sample deployment script to handle an Intel system in WinPE and Linux
"""

import os, os.path, sys
from deploymentData import *
import time
STATEVAR='DepState'

try:
    __file__
except:
    __file__ = __name__

from threading import Thread
class runScript(Thread):
    """
    script - full path to script file
    app - object to send output from script
    """
    def __init__ (self,script,app=0,state=0):
        Thread.__init__(self)
        self.script = script
        self.app = app
        self.state = state
        self.status = -1

    def myimport(self, globals=None, locals=None, fromlist=None):
        import imp
        dname = os.path.dirname(self.script)
        name = os.path.basename(self.script[:-3])
        # Fast path: see if the module has already been imported.
        try:
            return sys.modules[name]
        except KeyError:
            pass
    
        # If any of the following calls raises an exception,
        # there's a problem we can't handle -- let the caller handle it.
    
        fp, pathname, description = imp.find_module(name,[dname])
    
        try:
            return imp.load_module(name, fp, pathname, description)
        finally:
            # Since we may exit via an exception, close fp explicitly.
            if fp:
                fp.close()
    
    def run(self):
        mod = 0
        if self.script[-3:] == '.py':
            try:
                mod = self.myimport()
            except:
                if self.app:
                    self.app.updateDetail('\nImport script %s error\n\n' % self.script)
                    self.app.finishedScript()
                print 'Import script %s error' % self.script
                return FAILURE
        elif sys.platform == 'linux2':
            shscript = self.script + '.sh'
        elif sys.platform == 'win32':
            shscript = self.script + '.cmd'
        if not mod and not os.path.exists(shscript):
            if self.app:
                self.app.updateDetail("\nScript %s does not exist\n\n"%shscript)
                self.app.finishedScript()
            print "Script does not exist: "+shscript
            self.status = FAILURE
            return
        if self.app:
            if not self.app.runStateKey:
                self.app.runLock.acquire()
                if not self.app.running:
                    self.app.runLock.release()
                    self.status = FAILURE
                    return
            if self.state:
                self.app.updateState(self.state)
            else:
                print "No State !!!"
            self.app.updateDetail('begin script: %s\n'%self.script)
        else:
            print 'begin script: %s'%self.script
        if self.state:
            print dicStateInfo[self.state][STATEMSG]
        if mod:
            self.status = mod.runState()
            output = ''
        else:
            import random
            dir = os.path.dirname(self.script)
            cwd = os.getcwd()
            os.chdir(dir)
            #cmd = os.path.basename(self.script)
    
            fname = 'demoOutput' + str(random.randint(0,1000)) + '.txt'
            cmdstr = '\"'+shscript+'\"' + ' 1> ' + fname
            self.status = os.system(cmdstr)
            if os.path.exists(fname):
                f = open(fname)
                output = f.read()
                f.close()
                os.remove(fname)
            else:
                output = ""
            os.chdir(cwd)
        if self.app:
            self.app.updateDetail(output)
            self.app.updateDetail('end script: %s, status 0x%x\n'%(self.script,self.status))
            if self.app.runStateKey:
                self.app.finishedScript()
            else:
                self.app.runLock.release()
        else:
            print output
            print 'end script: %s, status 0x%x'%(self.script,self.status)

if TKDEMO:
    from tkdemo import startDemo
    class runDemo(Thread):
        scriptThread = 0
        def __init__ (self):
            Thread.__init__(self)
            self.demo = startDemo()
        def run(self):
            while self.demo.running:
                if self.demo.runStateKey:
                    self.scriptThread = runScript(dicStateInfo[self.demo.runStateKey][STATESCRIPT],self.demo,self.demo.runStateKey)
                    self.scriptThread.start()
                    #self.scriptThread.join()
                    #del self.scriptThread
                    #self.scriptThread = 0
                self.demo.mainloop()
            self.demo.runLock.release()
            
    demoApp = runDemo()
    demoApp.start()

from logMgr import getLogSeverity, LOG_LEVELS, addLogRecord,CRITICAL,ERROR,WARNING,INFO,DEBUG
import systemMgr
            
def systemReboot(target=''):
    if target:
        from syscfg.bioscfg import biosConfig
        biosConfig([target])    
    os.system('reboot')
    time.sleep(60)
    return FAILURE

def runState(state):
    if TKDEMO:
        global demoApp
        runThread = runScript(dicStateInfo[state][STATESCRIPT],demoApp.demo,state)
    else:
        runThread = runScript(dicStateInfo[state][STATESCRIPT])
    addLogRecord(0,__file__, INFO,dicStateInfo[state][STATELOGMSG])
    runThread.start()
    runThread.join()
    status = runThread.status
    del runThread
    if status == FAILURE:
        if TKDEMO:
            del demoApp
        #os.system("persistVariable delete %s"%(STATEVAR))
        sys.exit(FAILURE)
    if status == REBOOT:
        if TKDEMO:
            del demoApp
        if systemReboot():
            #os.system("persistVariable delete %s"%(STATEVAR))
            sys.exit(FAILURE)
    newstate = dicStateInfo[state][NEXTSTATE]
    os.system("persistVariable update %s=%x"%(STATEVAR,newstate))
    return newstate

print "run customized deployment scripts here ..."
print "execute a series of scripts of your own making ..."

InitialState=Sflash
if TKTEST:
    depstate=InitialState
    demoApp.demo.setPlatform('T43p')
else:
    ret, BoardFamily = systemMgr.queryProperty(0,'IntelBIOSID','BoardFamilyID','',{})
    if not BoardFamily or ret:
        addLogRecord(0,__file__, ERROR,'Board Family version unavailable: ret = %d'%ret)
        sys.exit(1)
    
    depstate = os.system("persistVariable read %s"%STATEVAR)
    if depstate < 0 or depstate == 0xff00:
        os.system("persistVariable update %s=%x"%(STATEVAR,Sflash))
        depstate = InitialState
    elif sys.platform == 'linux2':
        depstate = depstate >> 8

while depstate != FINISHED:
    depstate = runState(depstate)

print dicStateInfo[depstate][STATEMSG]
addLogRecord(0,__file__, INFO,dicStateInfo[depstate][STATELOGMSG])
print "finish Demo with log severity level: %s"% LOG_LEVELS[getLogSeverity(0)]
if TKDEMO:
    demoApp.demo.updateState(depstate)
    demoApp.join()
    del demoApp

sys.exit(0)

"""
    
if depstate == Sdisk:
    print dicStateInfo[depstate][STATEMSG]
    addLogRecord(0,__file__, INFO,dicStateInfo[depstate][STATELOGMSG])
    #call disk configuration script here
    os.system("persistVariable update %s=%x"%(STATEVAR,Sswraid))
    depstate = Sswraid
    
    
if depstate == Sos:
    print dicStateInfo[depstate][STATEMSG]
    addLogRecord(0,__file__, INFO,dicStateInfo[depstate][STATELOGMSG])
    #call OS installation script here
    from Sos import runState
    state = runState()
    if state == FAILURE:
        os.system("persistVariable delete %s"%(STATEVAR))
        sys.exit(FAILURE)
    if state == REBOOT:
        if systemReboot():
            os.system("persistVariable delete %s"%(STATEVAR))
            sys.exit(FAILURE)
    os.system("persistVariable update %s=%x"%(STATEVAR,Snet))
    depstate = Snet
    if systemReboot('disk'):
        os.system("persistVariable delete %s"%(STATEVAR))
        sys.exit(FAILURE)
    
if depstate == Snet:
    print dicStateInfo[depstate][STATEMSG]
    addLogRecord(0,__file__, INFO,dicStateInfo[depstate][STATELOGMSG])
    #call configuration script here
    os.system("persistVariable update %s=%x"%(STATEVAR,Srestore))
    depstate = Srestore
    
if depstate == Srestore:
    print dicStateInfo[depstate][STATEMSG]
    addLogRecord(0,__file__, INFO,dicStateInfo[depstate][STATELOGMSG])
    #call erase script here
    from Sos import installOS
    state = installOS(1)
    if state == FAILURE:
        os.system("persistVariable delete %s"%(STATEVAR))
        sys.exit(FAILURE)
    if state == REBOOT:
        if systemReboot():
            os.system("persistVariable delete %s"%(STATEVAR))
            sys.exit(FAILURE)
    from raid import createVolume
    state = createVolume(1,1) # 1 - HW RAID
    if state == FAILURE:
        os.system("persistVariable delete %s"%(STATEVAR))
        sys.exit(FAILURE)
    if state == REBOOT:
        if systemReboot():
            os.system("persistVariable delete %s"%(STATEVAR))
            sys.exit(FAILURE)
    state = createVolume(0,1) # 0 - SW RAID
    if state == FAILURE:
        os.system("persistVariable delete %s"%(STATEVAR))
        sys.exit(FAILURE)
    if state == REBOOT:
        if systemReboot():
            os.system("persistVariable delete %s"%(STATEVAR))
            sys.exit(FAILURE)
    from configFW import runState
    state = runState(1)
    if state == FAILURE:
        os.system("persistVariable delete %s"%(STATEVAR))
        sys.exit(FAILURE)
    if state == REBOOT:
        if systemReboot():
            os.system("persistVariable delete %s"%(STATEVAR))
            sys.exit(FAILURE)
"""
"""
    from flash import flash
    state = flash(1)
    if FAILURE:
        os.system("persistVariable delete %s"%(STATEVAR))
        sys.exit(state)
    if state == REBOOT:
        if systemReboot():
            os.system("persistVariable delete %s"%(STATEVAR))
            sys.exit(FAILURE)
"""
"""
    #os.system("persistVariable update %s=%x"%(STATEVAR,Sconfig))
    os.system("persistVariable delete %s"%(STATEVAR))
    depstate = FINISHED
"""
