class AndroidPackage(object):
    '''
    The APK operation class.
    '''


    def __init__(self):
        '''
        Constructor
        '''
        self.__tools = Tools()
        self.__serialNumber = []

    def __substituteStr(self, rowStr):
        '''
        substitute some string.
        '''
        if DEBUG:
            print "[EXEC] %s.%s" % (self.__class__.__name__, self.__tools.getCurrentFunctionName())

        tempStr = "'" + rowStr + "'"

        if DEBUG:
            print "+++++++++++++++++++++++++++++++++++++++++++++++++++++++"
            print "SUBSTITUTED_STR: %s" % tempStr
            print "+++++++++++++++++++++++++++++++++++++++++++++++++++++++"

        return tempStr

    def getPackageName(self, apkName):
        '''
        get the package name of the apk from the apk file.
        '''
        if DEBUG:
            print "[EXEC] %s.%s" % (self.__class__.__name__, self.__tools.getCurrentFunctionName())

        tempCmd = AAPT_DUMP_CMD % (self.__substituteStr(apkName), APK_PACKAGE_IDENTIFIER)

        if DEBUG:
            print "COMMAND: %s" % tempCmd

        try:
            popen = Popen(tempCmd, shell = True, stdout = PIPE, stderr = STDOUT)
            tempStr = popen.stdout.readline().split("'")[PACKAGE_NAME]

            if DEBUG:
                print "+++++++++++++++++++++++++++++++++++++++++++++++++++++++"
                print "APK_PACKAGE_NAME: %s" % tempStr
                print "+++++++++++++++++++++++++++++++++++++++++++++++++++++++"

            return tempStr

        except IndexError, e:
            print "[ERROR] %s" % e
            return FAILURE + " " + str(e)
class ExecutionThreadManager(object):
    '''
    classdocs
    '''


    def __init__(self):
        '''
        Constructor
        '''
        self.__tools = Tools()
        self.__taskQueue = Queue()
        self.__nonTaskQueue = Queue()
        self.__resultQueue = Queue()
        self.__threads = []

    def appendExecutionTask(self, func, args):
        '''
        append execution task.
        '''
        if DEBUG:
            print "[EXEC] %s.%s" % (self.__class__.__name__, self.__tools.getCurrentFunctionName())

        self.__threads.append(ExecutionThread(func, args + (self.__taskQueue, self.__nonTaskQueue)))

    def createThreadPool(self, func, args):
        '''
        create a thread pool.
        '''
        if DEBUG:
            print "[EXEC] %s.%s" % (self.__class__.__name__, self.__tools.getCurrentFunctionName())

        self.__threads.append(ExecutionThread(func, args + (self.__taskQueue, self.__resultQueue)))

    def waitForComplete(self, timeout = TIME_OUT):
        '''
        wait for all the theads finished.
        '''
        if DEBUG:
            print "[EXEC] %s.%s" % (self.__class__.__name__, self.__tools.getCurrentFunctionName())

        for thread in self.__threads:
            if thread.isAlive():
                thread.join(timeout)

    def getResult(self):
        '''
        return the result queue.
        '''
        if DEBUG:
            print "[EXEC] %s.%s" % (self.__class__.__name__, self.__tools.getCurrentFunctionName())

        return self.__resultQueue, self.__nonTaskQueue
class CsvFile(object):
    '''
    The csv file operation class.
    '''
    def __init__(self):
        '''
        Constructor
        '''
        self.__tools = Tools()
        self.__sheet = []

    def read(self, path=""):
        '''
        read the csv file.
        '''
        if DEBUG:
            print "[EXEC] %s.%s" % (self.__class__.__name__, self.__tools.getCurrentFunctionName())

        try:
            with open(path, "rb") as f:
                reader = csv.reader(f)
                for row in reader:
                    self.__sheet.append(row)
            return self.__sheet
        except (IOError, TypeError), e:
            print "[ERROR] %s" % e
            exit()
 def __init__(self):
     '''
     Constructor
     '''
     self.__tools = Tools()
     self.__taskQueue = Queue()
     self.__nonTaskQueue = Queue()
     self.__resultQueue = Queue()
     self.__threads = []
class Devices(object):
    '''
    The devices operation class.
    '''


    def __init__(self):
        '''
        Constructor
        '''
        self.__tools = Tools()
        self.__serialNumber = []

    def __keepAwake(self, serialNumber):
        '''
        keep the devices awake.
        '''
        if DEBUG:
            print "[EXEC] %s.%s" % (self.__class__.__name__, self.__tools.getCurrentFunctionName())

        tempCmd = ADB_SVC_CMD % serialNumber
        Popen(tempCmd, shell = True, stdout = PIPE, stderr = STDOUT) 

    def getSerialNumber(self):
        '''
        get the serial number of the online devices.
        '''
        if DEBUG:
            print "[EXEC] %s.%s" % (self.__class__.__name__, self.__tools.getCurrentFunctionName())

        popen = Popen(ADB_DEVICES_CMD, shell = True, stdout = PIPE, stderr = STDOUT)
        for row in popen.stdout.readlines():
            if DEVICES_IDENTIFIER in row:
                self.__serialNumber.append(row.split(DEVICES_IDENTIFIER)[SERIAL_NUMBER])

        if DEBUG:
            print "+++++++++++++++++++++++++++++++++++++++++++++++++++++++"
            print "DEVICES_SERIAL_NUMBER: %s" % self.__serialNumber
            print "+++++++++++++++++++++++++++++++++++++++++++++++++++++++"

        for tempStr in self.__serialNumber:
            self.__keepAwake(tempStr)

        return self.__serialNumber
 def __init__(self):
     '''
     Constructor
     '''
     self.__tools = Tools()
     self.__sheet = []
     self.__workbook = None
     self.__worksheet = None
     self.__titleStyle = easyxf('pattern: pattern solid, fore_colour gray25; font: bold on;');
     self.__successStyle = easyxf('pattern: pattern solid, fore_colour green');
     self.__failureStyle = easyxf('pattern: pattern solid, fore_colour red;');
 def __init__(self):
     """
     Constructor
     """
     self.__tools = Tools()
     self.__androidPackage = AndroidPackage()
     self.__operators = (
         self.__installOperation,
         self.__startOperation,
         self.__stopOperation,
         self.__uninstallOperation,
     )
 def __init__(self):
     '''
     Constructor
     '''
     self.__tools = Tools()
     self.__rootDirPath = None
     self.__csvFile = None
     self.__apkFileInfo = []
     self.__subApkFileInfo = []
     self.__brokenApk = []
     self.__androidPackage = AndroidPackage()
     self.__operator = [self.__androidPackage.getPackageName,
                        self.__androidPackage.getActivity,
                        self.__androidPackage.getVersionName,
                        self.__androidPackage.getName]
class XlsFile(object):
    '''
    The xls file operation class.
    '''


    def __init__(self):
        '''
        Constructor
        '''
        self.__tools = Tools()
        self.__sheet = []
        self.__workbook = None
        self.__worksheet = None
        self.__titleStyle = easyxf('pattern: pattern solid, fore_colour gray25; font: bold on;');
        self.__successStyle = easyxf('pattern: pattern solid, fore_colour green');
        self.__failureStyle = easyxf('pattern: pattern solid, fore_colour red;');

    def write(self, title, content, path = RUN_RESULTS_FILE):
        '''
        write content to the xls file.
        '''
        if DEBUG:
            print "[EXEC] %s.%s" % (self.__class__.__name__, self.__tools.getCurrentFunctionName())

        self.__workbook = Workbook(encoding = 'utf-8')
        self.__worksheet = self.__workbook.add_sheet('APK Test Result List')

        for rowNo in range(len(title)):
            self.__worksheet.write(TITLE, rowNo, title[rowNo], self.__titleStyle)

        for rowNo in range(content.qsize()):
            tempList = content.get()
            for columnNo in range(len(tempList)):
                if SUCCESS_STATUS == tempList[columnNo][STATUS]:
                    self.__worksheet.write(rowNo + 1, columnNo, tempList[columnNo][VALUE], self.__successStyle)
                elif FAILURE_STATUS == tempList[columnNo][STATUS]:
                    self.__worksheet.write(rowNo + 1, columnNo, tempList[columnNo][VALUE], self.__failureStyle)
                elif BLACK_STATUS == tempList[columnNo][STATUS]:
                    self.__worksheet.write(rowNo + 1, columnNo, tempList[columnNo][VALUE])
                else:
                    self.__worksheet.write(rowNo + 1, columnNo, tempList[columnNo][VALUE])

        self.__workbook.save(path)
 def __init__(self):
     '''
     Constructor
     '''
     self.__tools = Tools()
     self.__sheet = []
 def __init__(self):
     '''
     Constructor
     '''
     self.__tools = Tools()
     self.__serialNumber = []
class Execution(object):
    """
    This is a operation execution class.
    """

    def __init__(self):
        """
        Constructor
        """
        self.__tools = Tools()
        self.__androidPackage = AndroidPackage()
        self.__operators = (
            self.__installOperation,
            self.__startOperation,
            self.__stopOperation,
            self.__uninstallOperation,
        )

    def operation(self, serialNumber, args):
        """
        execute some operation.
        """
        if DEBUG:
            print "[EXEC] %s.%s" % (self.__class__.__name__, self.__tools.getCurrentFunctionName())

        print "[EXEC] %s" % args[APK_FILE_NAME][VALUE]

        tempList = args
        for i in range(len(self.__operators)):
            tempStr = self.__operators[i](args, serialNumber)
            if tempStr.upper().find(SUCCESS_IDENTIFIER) >= 0:
                tempSubList = [tempStr, SUCCESS_STATUS]
            else:
                tempSubList = [tempStr, FAILURE_STATUS]
            tempList.append(tempSubList)

        return tempList

    def __installOperation(self, args, serialNumber):
        """
        execute the installing apk operation.
        """
        if DEBUG:
            print "[EXEC] %s.%s" % (self.__class__.__name__, self.__tools.getCurrentFunctionName())

        return self.__androidPackage.install(
            serialNumber, os.path.join(args[APK_FILE_PATH][VALUE], args[APK_FILE_NAME][VALUE])
        )

    def __startOperation(self, args, serialNumber):
        """
        execute the starting apk operation.
        """
        if DEBUG:
            print "[EXEC] %s.%s" % (self.__class__.__name__, self.__tools.getCurrentFunctionName())

        return self.__androidPackage.start(serialNumber, args[APK_PACKAGE_NAME][VALUE], args[APK_ACTIVITY_NAME][VALUE])

    def __stopOperation(self, args, serialNumber):
        """
        execute the stopping apk operation.
        """
        if DEBUG:
            print "[EXEC] %s.%s" % (self.__class__.__name__, self.__tools.getCurrentFunctionName())

        return self.__androidPackage.stop(serialNumber, args[APK_PACKAGE_NAME][VALUE])

    def __uninstallOperation(self, args, serialNumber):
        """
        execute the uninstalling apk operation.
        """
        if DEBUG:
            print "[EXEC] %s.%s" % (self.__class__.__name__, self.__tools.getCurrentFunctionName())

        return self.__androidPackage.uninstall(serialNumber, args[APK_PACKAGE_NAME][VALUE])
class ApkFile(object):
    '''
    The APK files operation class.
    '''


    def __init__(self):
        '''
        Constructor
        '''
        self.__tools = Tools()
        self.__rootDirPath = None
        self.__csvFile = None
        self.__apkFileInfo = []
        self.__subApkFileInfo = []
        self.__brokenApk = []
        self.__androidPackage = AndroidPackage()
        self.__operator = [self.__androidPackage.getPackageName,
                           self.__androidPackage.getActivity,
                           self.__androidPackage.getVersionName,
                           self.__androidPackage.getName]

    def __getDirPathAndFileNames(self, path):
        '''
        get the apk file name and its dir path.
        '''
        if DEBUG:
            print "[EXEC] %s.%s" % (self.__class__.__name__, self.__tools.getCurrentFunctionName())

        for tempTuple in os.walk(path):
            for tempStr in tempTuple[FILE_NAMES]:
                if tempStr.endswith(APK_FILE_NAME_SUFFIX):
                    tempList = [[tempStr, BLACK_STATUS], [tempTuple[DIR_PATH], BLACK_STATUS]]
                    self.__subApkFileInfo.append(tempList)

        if DEBUG:
            print "+++++++++++++++++++++++++++++++++++++++++++++++++++++++"
            for r in range(len(self.__subApkFileInfo)):
                for c in range(len(self.__subApkFileInfo[r])):
                    print self.__subApkFileInfo[r][c]
                print "+++++++++++++++++++++++++++++++++++++++++++++++++++++++"

    def __getApkInfo(self, path, row):
        '''
        get all package info of the apk from the apk file.
        '''
        if DEBUG:
            print "[EXEC] %s.%s" % (self.__class__.__name__, self.__tools.getCurrentFunctionName())

        for tempList in self.__operator:
            tempStr = tempList(path)
            if tempStr.upper().find(FAILURE_IDENTIFIER) >= 0:
                tempSubList = [tempStr, FAILURE_STATUS]
            else:
                tempSubList = [tempStr, SUCCESS_STATUS]
            row.append(tempSubList)

        if DEBUG:
            print "+++++++++++++++++++++++++++++++++++++++++++++++++++++++"
            for r in row:
                print r
            print "+++++++++++++++++++++++++++++++++++++++++++++++++++++++"

    def __saveResult(self):
        '''
        save the error information.
        '''
        if DEBUG:
            print "[EXEC] %s.%s" % (self.__class__.__name__, self.__tools.getCurrentFunctionName())

        self.__csvFile = CsvFile()
        self.__csvFile.write(CONFIG_FILE, self.__brokenApk)

    def exportApkInfo(self, path, taskQueue, nonTaskQueue):
        '''
        export APK information to the csv file.
        '''
        if DEBUG:
            print "[EXEC] %s.%s" % (self.__class__.__name__, self.__tools.getCurrentFunctionName())

        self.__getDirPathAndFileNames(path)
        for row in self.__subApkFileInfo:
            self.__getApkInfo(os.path.join(row[APK_FILE_PATH][VALUE], row[APK_FILE_NAME][VALUE]), row)
            isSuccessful = True
            for tempList in row:
                if ''.join(tempList).upper().find(FAILURE_IDENTIFIER) >= 0:
                    isSuccessful = False
                    nonTaskQueue.put(row, True)
                    break
            if isSuccessful:
                taskQueue.put(row, True)
            sleep(0.1)