#!/usr/bin/python
# -*- coding: latin-1 -*-
# INTEL CONFIDENTIAL
# Copyright 2007 Intel Corporation All Rights Reserved.
#
# The source code contained or described herein and all documents related to the
# source code (Material) are owned by Intel Corporation or its suppliers or
# licensors. Title to the Material remains with Intel Corporation or its
# suppliers and licensors. The Material may contain trade secrets and
# proprietary and confidential information of Intel Corporation and its
# suppliers and licensors, and is protected by worldwide copyright and trade
# secret laws and treaty provisions. No part of the Material may be used,
# copied, reproduced, modified, published, uploaded, posted, transmitted,
# distributed, or disclosed in any way without Intels prior express written
# permission. 
# No license under any patent, copyright, trade secret or other intellectual
# property right is granted to or conferred upon you by disclosure or delivery
# of the Materials, either expressly, by implication, inducement, estoppel or
# otherwise. Any license under such intellectual property rights must be express
# and approved by Intel in writing.
#
# Include any supplier copyright notices as supplier requires Intel to use.
#
# Include supplier trademarks or logos as supplier requires Intel to use, preceded
# by an asterisk. An asterisked footnote can be added as follows:
# *Third Party trademarks are the property of their respective owners.
#
# Unless otherwise agreed by Intel in writing, you may not remove or alter this
# notice or any other notice embedded in Materials by Intel or Intels suppliers
# or licensors in any way.

""" This module invokes the methods to gather system data from a variety of sources
    begining with the SMBIOS data. The SystemInfo.xml file is built by prepareDeployment.
    If an existing SystemInfo.xml file exists, the system UUID is queried.
    Then is the UUID is different from the current system UUID, the SystemInfo.xml
    and the SystemLog.xml files are rename to include the previous UUID in the file names.
    The exiting SystemInfo.xml file for the current system is always removed and
    a new SystemInfo.xml is rebuilt whenever prepareDeployment is invoked.
    
    The appropriate device drivers are loaded as the system data is gathered. The
    system will hang in WinPE if a driver already has been loaded and is in use.
    'lsmod' in Linux is used to detect a loaded driver so a reload is avoided.
    There is no similar built in utility in WinPE so a 'refresh' parameter is needed
    to enable prepareDeployment to avoid driver reloads. By default drivers are loaded.
    """
__author__ = 'Todd C Davis'
__Product__ = 'Intel_PDK'

import systemMgr, sys, os, os.path, tempfile, shutil
from getSMBIOS import isSameUUID, readSMBIOSrecords, parseBcpId
from getFRUdata import readFRUrecords
from getAMTdata import readAMTrecords
from detectdisk import detectDisk
from detecteth import detectEth
from getRMM import readRMMdata
from detectBIOSRAID import detectBIOSRAID
from logMgr import addLogRecord,CRITICAL,ERROR,WARNING,INFO,DEBUG
from loadDrivers import loadDrivers, loadDiskDrivers, loadRAIDDrivers
from config import DeployPath,DeploymentStore
try:
    __file__
except:
    __file__ = __name__
if DeploymentStore:
    if not os.path.exists(os.path.join(DeploymentStore,'SystemInfo.xslt')):
        shutil.copy2(os.path.join(DeployPath,'xml','SystemInfo.xslt'),os.path.join(DeploymentStore,'SystemInfo.xslt'))
    if not os.path.exists(os.path.join(DeploymentStore,'SystemLog.xslt')):
        shutil.copy2(os.path.join(DeployPath,'xml','SystemLog.xslt'),os.path.join(DeploymentStore,'SystemLog.xslt'))

def fixCase():
    """
    SLAX mounts a FAT FS so that 'ENUS' becomes 'enus', 'S3000' becomes 's3000', etc
    """
    caseFiles = [
        [os.path.join('win32','syscfg','enus'),'ENUS'],
        [os.path.join('Linux','syscfg','enus'),'ENUS'],
        [os.path.join('doc','ofu','s3000'),'S3000'],
        [os.path.join('doc','ofu','s5000'),'S5000'],
        [os.path.join('Linux','DmiEdit','s3000'),'S3000'],
        [os.path.join('Linux','DmiEdit','s5000'),'S5000'],
        [os.path.join('doc','DmiEdit','s3000.dms'),'S3000.dms'],
        [os.path.join('doc','DmiEdit','s5000.dms'),'S5000.dms'],
    ]
    for files in caseFiles:
        filePath = os.path.join(DeployPath,files[0])
        if os.path.exists(filePath):
            os.rename(filePath,os.path.join(os.path.dirname(filePath),files[1]))

def fixLinks():
    """
    create any missing symbolic links for Linux systems
    """
    if not sys.platform == 'linux2':
        return
    OFUlibs = {
    'libbiosupdate.so.9' : 'libbiosupdate.so',
    'libbud.so.9'        : 'libbud.so',
    'libcfgfile.so.9'    : 'libcfgfile.so',
    'libfrudata.so.9'    : 'libfrudata.so',
    'libfwdupdate.so.9'  : 'libfwdupdate.so',
    'libfwupdate.so.9'   : 'libfwupdate.so',
    'libsdrdata.so.9'    : 'libsdrdata.so',
    'libsmbios.so.9'     : 'libsmbios.so',
    }
    for lib in OFUlibs.keys():
        if not os.path.exists(os.path.join(DeployPath,'Linux','libs',lib)):
            #os.symlink(os.path.join(DeployPath,'Linux','libs',OFUlibs[lib]),os.path.join(DeployPath,'Linux','libs',lib))
            os.system("cp %s %s"%(os.path.join(DeployPath,'Linux','libs',OFUlibs[lib]),os.path.join(DeployPath,'Linux','libs',lib)))

def loadFamily(family):
    """
    loads family specific files
    """
    familyFolders = [
        os.path.join('Linux','syscfg'),
        os.path.join('Linux','libs'),
    ]
    if family == 'S3000':
        family = 'S5000'
    for dir in familyFolders:
        src = os.path.join(DeployPath,dir,family)
        if os.path.exists(src):
            os.system("cp -r %s %s"%(os.path.join(src,'*'),os.path.dirname(src)))

def prepareDeployment(refresh=0):
    fixCase()
    ret, UUID = systemMgr.queryProperty(0,'SMBIOS','UUID','',{'type':'1'})
    if UUID and not isSameUUID(UUID):
        systemMgr.renameSystemInfoFile(UUID)
    systemMgr.removeSystemInfoFile()
    ret = readSMBIOSrecords()
    if ret:
        return ret
    ret, value = systemMgr.queryProperty(0,'SMBIOS','UUID','',{'type':'1'})
    if ret < 0:
        addLogRecord(0,__file__, CRITICAL, "Failed to read SMBIOS records")
        return ret
    addLogRecord(0,__file__, INFO, "Read SMBIOS records for UUID %s"%value)
    ret, family = systemMgr.queryProperty(0,'IntelBIOSID','BoardFamilyID','',{})
    if not family in ['S3000','S5000','S5500']:
        print "Unsupported baseboard family: %s"%family
        addLogRecord(0,__file__, CRITICAL, "Unsupported baseboard family: %s"%family)
        return 1
    if not refresh:
        ret = loadDrivers()
        if ret:
            addLogRecord(0,__file__, CRITICAL, "Failed to load drivers -- aborting")
            return ret
    ret, family = systemMgr.queryProperty(0,'IntelBIOSID','BoardFamilyID','',{})
    #if not refresh and family and ret == 0:
    #    loadFamily(family)
    #fixLinks()
    parseBcpId()
    if family and ret == 0:
        if family == 'S3000':
            readAMTrecords()
            ret, value = systemMgr.queryProperty(0,'AMT','BIOS version','',{})
            if ret < 0:
                addLogRecord(0,__file__, CRITICAL, "Failed to read AMT records")
                return ret
            addLogRecord(0,__file__, INFO, "Read AMT records for BIOS Version %s"%value)
        else:
            readFRUrecords()
            ret, value = systemMgr.queryProperty(0,'FRU','System GUID','',{'info':'Mainboard FRU'})
            if ret < 0:
                addLogRecord(0,__file__, CRITICAL, "Failed to read FRU records")
                return ret
            addLogRecord(0,__file__, INFO, "Read FRU records for UUID %s"%value)
    else:
        addLogRecord(0,__file__, CRITICAL, "Failed to read BIOS Version")
        return ret
    detectBIOSRAID()
    if not refresh:
        loadRAIDDrivers()
        loadDiskDrivers()
    detectEth()
    detectDisk()
    readRMMdata()
    return 0

if __name__ == '__main__':
    if len(sys.argv) == 1:
        refresh = 0
    elif len(sys.argv) == 2 and sys.argv[1] == '0':
        refresh = 0
    else:
        refresh = 1
    sys.exit(prepareDeployment(refresh))
