# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.

import select
import socket
import SocketServer
import time
import os
import re
import posixpath
import subprocess
from threading import Thread
import StringIO
from devicemanager import DeviceManager, FileError, DMError, NetworkTools, _pop_last_line
import errno
from distutils.version import StrictVersion


class AgentError(Exception):
    "SUTAgent-specific exception."

    def __init__(self, msg='', fatal=False):
        self.msg = msg
        self.fatal = fatal

    def __str__(self):
        return self.msg


class DeviceManagerSUT(DeviceManager):
    debug = 2
    tempRoot = os.getcwd()
    base_prompt = '$>'
    base_prompt_re = '\$\>'
    prompt_sep = '\x00'
    prompt_regex = '.*(' + base_prompt_re + prompt_sep + ')'
    agentErrorRE = re.compile('^##AGENT-WARNING##\ ?(.*)')
    default_timeout = 300

    # TODO: member variable to indicate error conditions.
    # This should be set to a standard error from the errno module.
    # So, for example, when an error occurs because of a missing file/directory,
    # before returning, the function would do something like 'self.error = errno.ENOENT'.
    # The error would be set where appropriate--so sendCMD() could set socket errors,
    # pushFile() and other file-related commands could set filesystem errors,
    # etc.

    def __init__(self, host, port=20701, retrylimit=5, deviceRoot=None):
        self.host = host
        self.port = port
        self.retrylimit = retrylimit
        self._sock = None
        self.deviceRoot = deviceRoot
        if self.getDeviceRoot() == None:
            raise BaseException("Failed to connect to SUT Agent and retrieve the device root.")
        try:
            verstring = self._runCmds([{'cmd': 'ver'}])
            self.agentVersion = re.sub(
                'SUTAgentAndroid Version ', '', verstring)
        except AgentError, err:
            raise BaseException("Failed to get SUTAgent version")

    def _cmdNeedsResponse(self, cmd):
        """ Not all commands need a response from the agent:
            * rebt obviously doesn't get a response
            * uninstall performs a reboot to ensure starting in a clean state and
              so also doesn't look for a response
        """
        noResponseCmds = [re.compile('^rebt'),
                          re.compile('^uninst .*$'),
                          re.compile('^pull .*$')]

        for c in noResponseCmds:
            if (c.match(cmd)):
                return False

        # If the command is not in our list, then it gets a response
        return True

    def _stripPrompt(self, data):
        """
        internal function
        take a data blob and strip instances of the prompt '$>\x00'
        """
        promptre = re.compile(self.prompt_regex + '.*')
        retVal = []
        lines = data.split('\n')
        for line in lines:
            foundPrompt = False
            try:
                while (promptre.match(line)):
                    foundPrompt = True
                    pieces = line.split(self.prompt_sep)
                    index = pieces.index('$>')
                    pieces.pop(index)
                    line = self.prompt_sep.join(pieces)
            except(ValueError):
                pass

            # we don't want to append lines that are blank after stripping the
            # prompt (those are basically "prompts")
            if not foundPrompt or line:
                retVal.append(line)

        return '\n'.join(retVal)

    def _shouldCmdCloseSocket(self, cmd):
        """
        Some commands need to close the socket after they are sent:
          * rebt
          * uninst
          * quit
        """
        socketClosingCmds = [re.compile('^quit.*'),
                             re.compile('^rebt.*'),
                             re.compile('^uninst .*$')]

        for c in socketClosingCmds:
            if (c.match(cmd)):
                return True
        return False

    def _sendCmds(self, cmdlist, outputfile, timeout=None):
        """
        Wrapper for _doCmds that loops up to self.retrylimit iterations
        """
        # this allows us to move the retry logic outside of the _doCmds() to make it
        # easier for debugging in the future.
        # note that since cmdlist is a list of commands, they will all be retried if
        # one fails.  this is necessary in particular for pushFile(), where we don't want
        # to accidentally send extra data if a failure occurs during data
        # transmission.

        retries = 0
        while retries < self.retrylimit:
            try:
                self._doCmds(cmdlist, outputfile, timeout)
                return
            except AgentError, err:
                # re-raise error if it's fatal (i.e. the device got the command but
                # couldn't execute it). retry otherwise
                if err.fatal:
                    raise err
                if self.debug >= 4:
                    print err
                retries += 1
                # if we lost the connection or failed to establish one, wait a
                # bit
                if retries < self.retrylimit and not self._sock:
                    sleep_time = 5 * retries
                    print 'Could not connect; sleeping for %d seconds.' % sleep_time
                    time.sleep(sleep_time)

        raise AgentError("Remote Device Error: unable to connect to %s after %s attempts" % (self.host, self.retrylimit))

    def _runCmds(self, cmdlist, timeout=None):
        """
        Similar to _sendCmds, but just returns any output as a string instead of
        writing to a file
        """
        outputfile = StringIO.StringIO()
        self._sendCmds(cmdlist, outputfile, timeout)
        outputfile.seek(0)
        return outputfile.read()

    def _doCmds(self, cmdlist, outputfile, timeout):
        promptre = re.compile(self.prompt_regex + '$')
        shouldCloseSocket = False

        if not timeout:
            # We are asserting that all commands will complete in this time
            # unless otherwise specified
            timeout = self.default_timeout

        if not self._sock:
            try:
                if self.debug >= 1:
                    print "reconnecting socket"
                self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            except socket.error, msg:
                self._sock = None
                raise AgentError(
                    "Automation Error: unable to create socket: " + str(msg))

            try:
                self._sock.connect((self.host, int(self.port)))
                if select.select([self._sock], [], [], timeout)[0]:
                    self._sock.recv(1024)
                else:
                    raise AgentError("Remote Device Error: Timeout in connecting", fatal=True)
                    return False
            except socket.error, msg:
                self._sock.close()
                self._sock = None
                raise AgentError("Remote Device Error: unable to connect socket: " + str(msg))

        for cmd in cmdlist:
            cmdline = '%s\r\n' % cmd['cmd']

            try:
                sent = self._sock.send(cmdline)
                if sent != len(cmdline):
                    raise AgentError("ERROR: our cmd was %s bytes and we "
                                     "only sent %s" % (len(cmdline), sent))
                if cmd.get('data'):
                    sent = self._sock.send(cmd['data'])
                    if sent != len(cmd['data']):
                            raise AgentError("ERROR: we had %s bytes of data to send, but "
                                             "only sent %s" % (len(cmd['data']), sent))

                if self.debug >= 4:
                    print "sent cmd: " + str(cmd['cmd'])
            except socket.error, msg:
                self._sock.close()
                self._sock = None
                if self.debug >= 1:
                    print "Remote Device Error: Error sending data to socket. cmd=" + str(cmd['cmd']) + "; err=" + str(msg)
                return False

            # Check if the command should close the socket
            shouldCloseSocket = self._shouldCmdCloseSocket(cmd['cmd'])

            # Handle responses from commands
            if self._cmdNeedsResponse(cmd['cmd']):
                foundPrompt = False
                data = ""
                timer = 0
                select_timeout = 1
                commandFailed = False

                while not foundPrompt:
                    socketClosed = False
                    errStr = ''
                    temp = ''
                    if self.debug >= 4:
                        print "recv'ing..."

                    # Get our response
                    try:
                          # Wait up to a second for socket to become ready for
                          # reading...
                        if select.select([self._sock], [], [], select_timeout)[0]:
                            temp = self._sock.recv(1024)
                            if self.debug >= 4:
                                print "response: " + str(temp)
                            timer = 0
                            if not temp:
                                socketClosed = True
                                errStr = 'connection closed'
                        timer += select_timeout
                        if timer > timeout:
                            raise AgentError("Automation Error: Timeout in command %s" % cmd['cmd'], fatal=True)
                    except socket.error, err:
                        socketClosed = True
                        errStr = str(err)
                        # This error shows up with we have our tegra rebooted.
                        if err[0] == errno.ECONNRESET:
                            errStr += ' - possible reboot'

                    if socketClosed:
                        self._sock.close()
                        self._sock = None
                        raise AgentError("Automation Error: Error receiving data from socket. cmd=%s; err=%s" % (cmd, errStr))

                    data += temp

                    # If something goes wrong in the agent it will send back a string that
                    # starts with '##AGENT-WARNING##'
                    if not commandFailed:
                        errorMatch = self.agentErrorRE.match(data)
                        if errorMatch:
                            # We still need to consume the prompt, so raise an error after
                            # draining the rest of the buffer.
                            commandFailed = True

                    for line in data.splitlines():
                        if promptre.match(line):
                            foundPrompt = True
                            data = self._stripPrompt(data)
                            break

                    # periodically flush data to output file to make sure it doesn't get
                    # too big/unwieldly
                    if len(data) > 1024:
                            outputfile.write(data[0:1024])
                            data = data[1024:]

                if commandFailed:
                    raise AgentError("Automation Error: Agent Error processing command '%s'; err='%s'" %
                                    (cmd['cmd'], errorMatch.group(1)), fatal=True)

                # Write any remaining data to outputfile
                outputfile.write(data)

        if shouldCloseSocket:
            try:
                self._sock.close()
                self._sock = None
            except:
                self._sock = None
                raise AgentError("Automation Error: Error closing socket")

    def shell(self, cmd, outputfile, env=None, cwd=None, timeout=None, root=False):
        """
        Executes shell command on device.

        cmd - Command string to execute
        outputfile - File to store output
        env - Environment to pass to exec command
        cwd - Directory to execute command from
        timeout - specified in seconds, defaults to 'default_timeout'
        root - Specifies whether command requires root privileges

        returns:
          success: Return code from command
          failure: None
        """

        cmdline = self._escapedCommandLine(cmd)
        if env:
            cmdline = '%s %s' % (self._formatEnvString(env), cmdline)

        haveExecSu = (
            StrictVersion(self.agentVersion) >= StrictVersion('1.13'))

        # Depending on agent version we send one of the following commands here:
        # * exec (run as normal user)
        # * execsu (run as privileged user)
        # * execcwd (run as normal user from specified directory)
        # * execcwdsu (run as privileged user from specified directory)

        cmd = "exec"
        if cwd:
            cmd += "cwd"
        if root and haveExecSu:
            cmd += "su"

        try:
            if cwd:
                self._sendCmds([{'cmd': '%s %s %s' % (cmd,
                               cwd, cmdline)}], outputfile, timeout)
            else:
                if (not root) or haveExecSu:
                    self._sendCmds([{'cmd': '%s %s' % (
                        cmd, cmdline)}], outputfile, timeout)
                else:
                    # need to manually inject su -c for backwards compatibility (this may
                    # not work on ICS or above!!)
                    # (FIXME: this backwards compatibility code is really ugly and should
                    # be deprecated at some point in the future)
                    self._sendCmds(
                        [{'cmd': '%s su -c "%s"' %
                            (cmd, cmdline)}], outputfile,
                        timeout)
        except AgentError:
            return None

        # dig through the output to get the return code
        lastline = _pop_last_line(outputfile)
        if lastline:
            m = re.search('return code \[([0-9]+)\]', lastline)
            if m:
                return int(m.group(1))

        # woops, we couldn't find an end of line/return value
        return None

    def pushFile(self, localname, destname):
        """
        Copies localname from the host to destname on the device

        returns:
          success: True
          failure: False
        """
        if (os.name == "nt"):
            destname = destname.replace('\\', '/')

        if (self.debug >= 3):
            print "in push file with: " + localname + ", and: " + destname
        if (self.dirExists(destname)):
            if (not destname.endswith('/')):
                destname = destname + '/'
            destname = destname + os.path.basename(localname)
        if (self.validateFile(destname, localname) == True):
            if (self.debug >= 3):
                print "files are validated"
            return True

        self.mkDirs(destname)

        if (self.debug >= 3):
            print "sending: push " + destname

        filesize = os.path.getsize(localname)
        f = open(localname, 'rb')
        data = f.read()
        f.close()

        try:
            retVal = self._runCmds(
                [{'cmd': 'push ' + destname + ' ' + str(filesize),
                  'data': data}])
        except AgentError, e:
            print "Automation Error: error pushing file: %s" % e.msg
            return False

        if (self.debug >= 3):
            print "push returned: " + str(retVal)

        validated = False
        if (retVal):
            retline = retVal.strip()
            if (retline == None):
                # Then we failed to get back a hash from agent, try manual
                # validation
                validated = self.validateFile(destname, localname)
            else:
                # Then we obtained a hash from push
                localHash = self._getLocalHash(localname)
                if (str(localHash) == str(retline)):
                    validated = True
        else:
            # We got nothing back from sendCMD, try manual validation
            validated = self.validateFile(destname, localname)

        if (validated):
            if (self.debug >= 3):
                print "Push File Validated!"
            return True
        else:
            if (self.debug >= 2):
                print "Automation Error: Push File Failed to Validate!"
            return False

    def mkDir(self, name):
        """
        Creates a single directory on the device file system

        returns:
          success: directory name
          failure: None
        """
        if (self.dirExists(name)):
            return name
        else:
            try:
                retVal = self._runCmds([{'cmd': 'mkdr ' + name}])
            except AgentError:
                retVal = None
            return retVal

    def pushDir(self, localDir, remoteDir):
        """
        Push localDir from host to remoteDir on the device

        returns:
          success: remoteDir
          failure: None
        """
        if (self.debug >= 2):
            print "pushing directory: %s to %s" % (localDir, remoteDir)
        for root, dirs, files in os.walk(localDir, followlinks=True):
            parts = root.split(localDir)
            for f in files:
                remoteRoot = remoteDir + '/' + parts[1]
                if (remoteRoot.endswith('/')):
                    remoteName = remoteRoot + f
                else:
                    remoteName = remoteRoot + '/' + f
                if (parts[1] == ""):
                    remoteRoot = remoteDir
                if (self.pushFile(os.path.join(root, f), remoteName) == False):
                    # retry once
                    self.removeFile(remoteName)
                    if (self.pushFile(os.path.join(root, f), remoteName) == False):
                        return None
        return remoteDir

    def dirExists(self, dirname):
        """
        Checks if dirname exists and is a directory
        on the device file system

        returns:
          success: True
          failure: False
        """
        match = ".*" + dirname.replace('^', '\^') + "$"
        dirre = re.compile(match)
        try:
            data = self._runCmds([{'cmd': 'cd ' + dirname}, {'cmd': 'cwd'}])
        except AgentError:
            return False

        found = False
        for d in data.splitlines():
            if (dirre.match(d)):
                found = True

        return found

    # Because we always have / style paths we make this a lot easier with some
    # assumptions
    def fileExists(self, filepath):
        """
        Checks if filepath exists and is a file on
        the device file system

        returns:
          success: True
          failure: False
        """
        s = filepath.split('/')
        containingpath = '/'.join(s[:-1])
        listfiles = self.listFiles(containingpath)
        for f in listfiles:
            if (f == s[-1]):
                return True
        return False

    def listFiles(self, rootdir):
        """
        Lists files on the device rootdir

        returns:
          success: array of filenames, ['file1', 'file2', ...]
          failure: None
        """
        rootdir = rootdir.rstrip('/')
        if (self.dirExists(rootdir) == False):
            return []
        try:
            data = self._runCmds([{'cmd': 'cd ' + rootdir}, {'cmd': 'ls'}])
        except AgentError:
            return []

        files = filter(lambda x: x, data.splitlines())
        if len(files) == 1 and files[0] == '<empty>':
            # special case on the agent: empty directories return just the
            # string "<empty>"
            return []
        return files

    def removeFile(self, filename):
        """
        Removes filename from the device

        returns:
          success: output of telnet
          failure: None
        """
        if (self.debug >= 2):
            print "removing file: " + filename
        try:
            retVal = self._runCmds([{'cmd': 'rm ' + filename}])
        except AgentError:
            return None

        return retVal

    def removeDir(self, remoteDir):
        """
        Does a recursive delete of directory on the device: rm -Rf remoteDir

        returns:
          success: output of telnet
          failure: None
        """
        try:
            retVal = self._runCmds([{'cmd': 'rmdr ' + remoteDir}])
        except AgentError:
            return None

        return retVal

    def getProcessList(self):
        """
        Lists the running processes on the device

        returns:
          success: array of process tuples
          failure: []
        """
        try:
            data = self._runCmds([{'cmd': 'ps'}])
        except AgentError:
            return []

        files = []
        for line in data.splitlines():
            if line:
                pidproc = line.strip().split()
                if (len(pidproc) == 2):
                    files += [[pidproc[0], pidproc[1]]]
                elif (len(pidproc) == 3):
                    # android returns <userID> <procID> <procName>
                    files += [[pidproc[1], pidproc[2], pidproc[0]]]
        return files

    def fireProcess(self, appname, failIfRunning=False):
        """
        DEPRECATED: Use shell() or launchApplication() for new code

        returns:
          success: pid
          failure: None
        """
        if (not appname):
            if (self.debug >= 1):
                print "WARNING: fireProcess called with no command to run"
            return None

        if (self.debug >= 2):
            print "FIRE PROC: '" + appname + "'"

        if (self.processExist(appname) != None):
            print "WARNING: process %s appears to be running already\n" % appname
            if (failIfRunning):
                return None

        try:
            self._runCmds([{'cmd': 'exec ' + appname}])
        except AgentError:
            return None

        # The 'exec' command may wait for the process to start and end, so checking
        # for the process here may result in process = None.
        process = self.processExist(appname)
        if (self.debug >= 4):
            print "got pid: %s for process: %s" % (process, appname)

        return process

    def launchProcess(self, cmd, outputFile="process.txt", cwd='', env='', failIfRunning=False):
        """
        DEPRECATED: Use shell() or launchApplication() for new code

        returns:
          success: output filename
          failure: None
        """
        if not cmd:
            if (self.debug >= 1):
                print "WARNING: launchProcess called without command to run"
            return None

        cmdline = subprocess.list2cmdline(cmd)
        if (outputFile == "process.txt" or outputFile == None):
            outputFile = self.getDeviceRoot();
            if outputFile is None:
                return None
            outputFile += "/process.txt"
            cmdline += " > " + outputFile

        # Prepend our env to the command
        cmdline = '%s %s' % (self._formatEnvString(env), cmdline)

        if self.fireProcess(cmdline, failIfRunning) is None:
            return None
        return outputFile

    def killProcess(self, appname, forceKill=False):
        """
        Kills the process named appname.
        If forceKill is True, process is killed regardless of state

        returns:
          success: True
          failure: False
        """
        if forceKill:
            print "WARNING: killProcess(): forceKill parameter unsupported on SUT"
        try:
            self._runCmds([{'cmd': 'kill ' + appname}])
        except AgentError:
            return False

        return True

    def getTempDir(self):
        """
        Gets the temporary directory we are using on this device
        base on our device root, ensuring also that it exists.

        returns:
          success: path for temporary directory
          failure: None
        """
        try:
            data = self._runCmds([{'cmd': 'tmpd'}])
        except AgentError:
            return None

        return data.strip()

    def catFile(self, remoteFile):
        """
        Returns the contents of remoteFile

        returns:
          success: filecontents, string
          failure: None
        """
        try:
            data = self._runCmds([{'cmd': 'cat ' + remoteFile}])
        except AgentError:
            return None

        return data

    def pullFile(self, remoteFile):
        """
        Returns contents of remoteFile using the "pull" command.

        returns:
          success: output of pullfile, string
          failure: None
        """
        # The "pull" command is different from other commands in that DeviceManager
        # has to read a certain number of bytes instead of just reading to the
        # next prompt.  This is more robust than the "cat" command, which will be
        # confused if the prompt string exists within the file being catted.
        # However it means we can't use the response-handling logic in
        # sendCMD().

        def err(error_msg):
            err_str = 'DeviceManager: pull unsuccessful: %s' % error_msg
            print err_str
            self._sock = None
            raise FileError(err_str)

        # FIXME: We could possibly move these socket-reading functions up to
        # the class level if we wanted to refactor sendCMD().  For now they are
        # only used to pull files.

        def uread(to_recv, error_msg, timeout=None):
            """ unbuffered read """
            timer = 0
            select_timeout = 1
            if not timeout:
                timeout = self.default_timeout

            try:
                if select.select([self._sock], [], [], select_timeout)[0]:
                    data = self._sock.recv(to_recv)
                    timer = 0
                timer += select_timeout
                if timer > timeout:
                    err('timeout in uread while retrieving file')
                    return None

                if not data:
                    err(error_msg)
                    return None
                return data
            except:
                err(error_msg)
                return None

        def read_until_char(c, buf, error_msg):
            """ read until 'c' is found; buffer rest """
            while not '\n' in buf:
                data = uread(1024, error_msg)
                if data == None:
                    err(error_msg)
                    return ('', '', '')
                buf += data
            return buf.partition(c)

        def read_exact(total_to_recv, buf, error_msg):
            """ read exact number of 'total_to_recv' bytes """
            while len(buf) < total_to_recv:
                to_recv = min(total_to_recv - len(buf), 1024)
                data = uread(to_recv, error_msg)
                if data == None:
                    return None
                buf += data
            return buf

        prompt = self.base_prompt + self.prompt_sep
        buf = ''

        # expected return value:
        # <filename>,<filesize>\n<filedata>
        # or, if error,
        # <filename>,-1\n<error message>
        try:
            # just send the command first, we read the response inline below
            self._runCmds([{'cmd': 'pull ' + remoteFile}])
        except AgentError:
            return None

        # read metadata; buffer the rest
        metadata, sep, buf = read_until_char(
            '\n', buf, 'could not find metadata')
        if not metadata:
            return None
        if self.debug >= 3:
            print 'metadata: %s' % metadata

        filename, sep, filesizestr = metadata.partition(',')
        if sep == '':
            err('could not find file size in returned metadata')
            return None
        try:
            filesize = int(filesizestr)
        except ValueError:
            err('invalid file size in returned metadata')
            return None

        if filesize == -1:
            # read error message
            error_str, sep, buf = read_until_char(
                '\n', buf, 'could not find error message')
            if not error_str:
                return None
            # prompt should follow
            read_exact(len(prompt), buf, 'could not find prompt')
            # failures are expected, so don't use "Remote Device Error" or
            # we'll RETRY
            print "DeviceManager: pulling file '%s' unsuccessful: %s" % (remoteFile, error_str)
            return None

        # read file data
        total_to_recv = filesize + len(prompt)
        buf = read_exact(total_to_recv, buf, 'could not get all file data')
        if buf == None:
            return None
        if buf[-len(prompt):] != prompt:
            err('no prompt found after file data--DeviceManager may be out of sync with agent')
            return buf
        return buf[:-len(prompt)]

    def getFile(self, remoteFile, localFile=''):
        """
        Copy file from device (remoteFile) to host (localFile)

        returns:
          success: contents of file, string
          failure: None
        """
        if localFile == '':
            localFile = os.path.join(self.tempRoot, "temp.txt")

        try:
            retVal = self.pullFile(remoteFile)
        except:
            return None

        if (retVal is None):
            return None

        fhandle = open(localFile, 'wb')
        fhandle.write(retVal)
        fhandle.close()
        if not self.validateFile(remoteFile, localFile):
            print 'DeviceManager: failed to validate file when downloading %s' % remoteFile
            return None
        return retVal

    def getDirectory(self, remoteDir, localDir, checkDir=True):
        """
        Copy directory structure from device (remoteDir) to host (localDir)

        returns:
          success: list of files, string
          failure: None
        """
        if (self.debug >= 2):
            print "getting files in '" + remoteDir + "'"
        if checkDir:
            try:
                is_dir = self.isDir(remoteDir)
            except FileError:
                return None
            if not is_dir:
                return None

        filelist = self.listFiles(remoteDir)
        if (self.debug >= 3):
            print filelist
        if not os.path.exists(localDir):
            os.makedirs(localDir)

        for f in filelist:
            if f == '.' or f == '..':
                continue
            remotePath = remoteDir + '/' + f
            localPath = os.path.join(localDir, f)
            try:
                is_dir = self.isDir(remotePath)
            except FileError:
                print 'isdir failed on file "%s"; continuing anyway...' % remotePath
                continue
            if is_dir:
                if (self.getDirectory(remotePath, localPath, False) == None):
                    print 'Remote Device Error: failed to get directory "%s"' % remotePath
                    return None
            else:
                # It's sometimes acceptable to have getFile() return None, such as
                # when the agent encounters broken symlinks.
                # FIXME: This should be improved so we know when a file transfer really
                # failed.
                if self.getFile(remotePath, localPath) == None:
                    print 'failed to get file "%s"; continuing anyway...' % remotePath
        return filelist

    def isDir(self, remotePath):
        """
        Checks if remotePath is a directory on the device

        returns:
          success: True
          failure: False
        """
        try:
            data = self._runCmds([{'cmd': 'isdir ' + remotePath}])
        except AgentError:
            # normally there should be no error here; a nonexistent file/directory will
            # return the string "<filename>: No such file or directory".
            # However, I've seen AGENT-WARNING returned before.
            return False

        retVal = data.strip()
        if not retVal:
            raise FileError('isdir returned null')
        return retVal == 'TRUE'

    def validateFile(self, remoteFile, localFile):
        """
        Checks if the remoteFile has the same md5 hash as the localFile

        returns:
          success: True
          failure: False
        """
        remoteHash = self._getRemoteHash(remoteFile)
        localHash = self._getLocalHash(localFile)

        if (remoteHash == None):
            return False

        if (remoteHash == localHash):
            return True

        return False

    def _getRemoteHash(self, filename):
        """
        Return the md5 sum of a file on the device

        returns:
          success: MD5 hash for given filename
          failure: None
        """
        try:
            data = self._runCmds([{'cmd': 'hash ' + filename}])
        except AgentError:
            return None

        retVal = None
        if data:
            retVal = data.strip()
        if self.debug >= 3:
            print "remote hash returned: '%s'" % retVal
        return retVal

    def getDeviceRoot(self):
        """
        Gets the device root for the testing area on the device
        For all devices we will use / type slashes and depend on the device-agent
        to sort those out.  The agent will return us the device location where we
        should store things, we will then create our /tests structure relative to
        that returned path.
        Structure on the device is as follows:
        /tests
            /<fennec>|<firefox>  --> approot
            /profile
            /xpcshell
            /reftest
            /mochitest

        returns:
          success: path for device root
          failure: None
        """
        if self.deviceRoot:
            deviceRoot = self.deviceRoot
        else:
            try:
                data = self._runCmds([{'cmd': 'testroot'}])
            except BaseException as e:
                print "Caught Exception:", e
                return None

            deviceRoot = data.strip() + '/tests'

        if (not self.dirExists(deviceRoot)):
            if (self.mkDir(deviceRoot) == None):
                return None

        self.deviceRoot = deviceRoot
        return self.deviceRoot

    def getAppRoot(self, packageName):
        """
        Returns the app root directory
        E.g /tests/fennec or /tests/firefox

        returns:
          success: path for app root
          failure: None
        """
        try:
            data = self._runCmds([{'cmd': 'getapproot ' + packageName}])
        except:
            return None

        return data.strip()

    def unpackFile(self, file_path, dest_dir=None):
        """
        Unzips a remote bundle to a remote location
        If dest_dir is not specified, the bundle is extracted
        in the same directory

        returns:
          success: output of unzip command
          failure: None
        """
        devroot = self.getDeviceRoot()
        if (devroot == None):
            return None

        # if no dest_dir is passed in just set it to file_path's folder
        if not dest_dir:
            dest_dir = posixpath.dirname(file_path)

        if dest_dir[-1] != '/':
            dest_dir += '/'

        try:
            data = self._runCmds(
                [{'cmd': 'unzp %s %s' % (file_path, dest_dir)}])
        except AgentError:
            return None

        return data

    def reboot(self, ipAddr=None, port=30000):
        """
        Reboots the device

        returns:
          success: status from test agent
          failure: None
        """
        cmd = 'rebt'

        if (self.debug > 3):
            print "INFO: sending rebt command"

        if (ipAddr is not None):
        # create update.info file:
            try:
                destname = '/data/data/com.mozilla.SUTAgentAndroid/files/update.info'
                data = "%s,%s\rrebooting\r" % (ipAddr, port)
                self._runCmds([{'cmd': 'push %s %s' % (
                    destname, len(data)), 'data': data}])
            except AgentError:
                return None

            ip, port = self._getCallbackIpAndPort(ipAddr, port)
            cmd += " %s %s" % (ip, port)
            # Set up our callback server
            callbacksvr = callbackServer(ip, port, self.debug)

        try:
            status = self._runCmds([{'cmd': cmd}])
        except AgentError:
            return None

        if (ipAddr is not None):
            status = callbacksvr.disconnect()

        if (self.debug > 3):
            print "INFO: rebt- got status back: " + str(status)
        return status

    def getInfo(self, directive=None):
        """
        Returns information about the device:
        Directive indicates the information you want to get, your choices are:
          os - name of the os
          id - unique id of the device
          uptime - uptime of the device
          uptimemillis - uptime of the device in milliseconds (NOT supported on all implementations)
          systime - system time of the device
          screen - screen resolution
          memory - memory stats
          process - list of running processes (same as ps)
          disk - total, free, available bytes on disk
          power - power status (charge, battery temp)
          all - all of them - or call it with no parameters to get all the information

        returns:
          success: dict of info strings by directive name
          failure: None
        """
        data = None
        result = {}
        collapseSpaces = re.compile('  +')

        directives = [
            'os', 'id', 'uptime', 'uptimemillis', 'systime', 'screen',
            'rotation', 'memory', 'process', 'disk', 'power']
        if (directive in directives):
            directives = [directive]

        for d in directives:
            try:
                data = self._runCmds([{'cmd': 'info ' + d}])
            except AgentError:
                return result

            if (data is None):
                continue
            data = collapseSpaces.sub(' ', data)
            result[d] = data.split('\n')

        # Get rid of any 0 length members of the arrays
        for k, v in result.iteritems():
            result[k] = filter(lambda x: x != '', result[k])

        # Format the process output
        if 'process' in result:
            proclist = []
            for l in result['process']:
                if l:
                    proclist.append(l.split('\t'))
            result['process'] = proclist

        if (self.debug >= 3):
            print "results: " + str(result)
        return result

    def installApp(self, appBundlePath, destPath=None):
        """
        Installs an application onto the device
        appBundlePath - path to the application bundle on the device
        destPath - destination directory of where application should be installed to (optional)

        returns:
          success: None
          failure: error string
        """
        cmd = 'inst ' + appBundlePath
        if destPath:
            cmd += ' ' + destPath

        try:
            data = self._runCmds([{'cmd': cmd}])
        except AgentError, err:
            print "Remote Device Error: Error installing app: %s" % err
            return "%s" % err

        f = re.compile('Failure')
        for line in data.split():
            if (f.match(line)):
                return line
        return None

    def uninstallApp(self, appName, installPath=None):
        """
        Uninstalls the named application from device and DOES NOT cause a reboot
        appName - the name of the application (e.g org.mozilla.fennec)
        installPath - the path to where the application was installed (optional)

        returns:
          success: None
          failure: DMError exception thrown
        """
        cmd = 'uninstall ' + appName
        if installPath:
            cmd += ' ' + installPath
        try:
            data = self._runCmds([{'cmd': cmd}])
        except AgentError, err:
            raise DMError(
                "Remote Device Error: Error uninstalling all %s" % appName)

        status = data.split('\n')[0].strip()
        if self.debug > 3:
            print "uninstallApp: '%s'" % status
        if status == 'Success':
            return
        raise DMError("Remote Device Error: uninstall failed for %s" % appName)

    def uninstallAppAndReboot(self, appName, installPath=None):
        """
        Uninstalls the named application from device and causes a reboot
        appName - the name of the application (e.g org.mozilla.fennec)
        installPath - the path to where the application was installed (optional)

        returns:
          success: None
          failure: DMError exception thrown
        """
        cmd = 'uninst ' + appName
        if installPath:
            cmd += ' ' + installPath
        try:
            data = self._runCmds([{'cmd': cmd}])
        except AgentError:
            raise DMError(
                "Remote Device Error: uninstall failed for %s" % appName)

        if (self.debug > 3):
            print "uninstallAppAndReboot: " + str(data)
        return

    def updateApp(self, appBundlePath, processName=None, destPath=None, ipAddr=None, port=30000):
        """
        Updates the application on the device.
        appBundlePath - path to the application bundle on the device
        processName - used to end the process if the applicaiton is currently running (optional)
        destPath - Destination directory to where the application should be installed (optional)
        ipAddr - IP address to await a callback ping to let us know that the device has updated
                 properly - defaults to current IP.
        port - port to await a callback ping to let us know that the device has updated properly
               defaults to 30000, and counts up from there if it finds a conflict

        returns:
          success: text status from command or callback server
          failure: None
        """
        status = None
        cmd = 'updt '
        if (processName == None):
            # Then we pass '' for processName
            cmd += "'' " + appBundlePath
        else:
            cmd += processName + ' ' + appBundlePath

        if (destPath):
            cmd += " " + destPath

        if (ipAddr is not None):
            ip, port = self._getCallbackIpAndPort(ipAddr, port)
            cmd += " %s %s" % (ip, port)
            # Set up our callback server
            callbacksvr = callbackServer(ip, port, self.debug)

        if (self.debug >= 3):
            print "INFO: updateApp using command: " + str(cmd)

        try:
            status = self._runCmds([{'cmd': cmd}])
        except AgentError:
            return None

        if ipAddr is not None:
            status = callbacksvr.disconnect()

        if (self.debug >= 3):
            print "INFO: updateApp: got status back: " + str(status)

        return status

    def getCurrentTime(self):
        """
        Returns device time in milliseconds since the epoch

        returns:
          success: time in ms
          failure: None
        """
        try:
            data = self._runCmds([{'cmd': 'clok'}])
        except AgentError:
            return None

        return data.strip()

    def _getCallbackIpAndPort(self, aIp, aPort):
        """
        Connect the ipaddress and port for a callback ping.  Defaults to current IP address
        And ports starting at 30000.
        NOTE: the detection for current IP address only works on Linux!
        """
        ip = aIp
        nettools = NetworkTools()
        if (ip == None):
            ip = nettools.getLanIp()
        if (aPort != None):
            port = nettools.findOpenPort(ip, aPort)
        else:
            port = nettools.findOpenPort(ip, 30000)
        return ip, port

    def _formatEnvString(self, env):
        """
        Returns a properly formatted env string for the agent.
        Input - env, which is either None, '', or a dict
        Output - a quoted string of the form: '"envvar1=val1,envvar2=val2..."'
        If env is None or '' return '' (empty quoted string)
        """
        if (env == None or env == ''):
            return ''

        retVal = '"%s"' % ','.join(
            map(lambda x: '%s=%s' % (x[0], x[1]), env.iteritems()))
        if (retVal == '""'):
            return ''

        return retVal

    def adjustResolution(self, width=1680, height=1050, type='hdmi'):
        """
        adjust the screen resolution on the device, REBOOT REQUIRED
        NOTE: this only works on a tegra ATM
        return:
          success: True
          failure: False

        supported resolutions: 640x480, 800x600, 1024x768, 1152x864, 1200x1024, 1440x900, 1680x1050, 1920x1080
        """
        if self.getInfo('os')['os'][0].split()[0] != 'harmony-eng':
            if (self.debug >= 2):
                print "WARNING: unable to adjust screen resolution on non Tegra device"
            return False

        results = self.getInfo('screen')
        parts = results['screen'][0].split(':')
        if (self.debug >= 3):
            print "INFO: we have a current resolution of %s, %s" % (parts[1].split()[0], parts[2].split()[0])

        # verify screen type is valid, and set it to the proper value
        # (https://bugzilla.mozilla.org/show_bug.cgi?id=632895#c4)
        screentype = -1
        if (type == 'hdmi'):
            screentype = 5
        elif (type == 'vga' or type == 'crt'):
            screentype = 3
        else:
            return False

        # verify we have numbers
        if not (isinstance(width, int) and isinstance(height, int)):
            return False

        if (width < 100 or width > 9999):
            return False

        if (height < 100 or height > 9999):
            return False

        if (self.debug >= 3):
            print "INFO: adjusting screen resolution to %s, %s and rebooting" % (width, height)
        try:
            self._runCmds([{'cmd': "exec setprop persist.tegra.dpy%s.mode.width %s" % (screentype, width)}])
            self._runCmds([{'cmd': "exec setprop persist.tegra.dpy%s.mode.height %s" % (screentype, height)}])
        except AgentError:
            return False

        return True

    def chmodDir(self, remoteDir, **kwargs):
        """
        Recursively changes file permissions in a directory

        returns:
          success: True
          failure: False
        """
        try:
            self._runCmds([{'cmd': "chmod " + remoteDir}])
        except AgentError:
            return False
        return True

gCallbackData = ''


class myServer(SocketServer.TCPServer):
    allow_reuse_address = True


class callbackServer():
    def __init__(self, ip, port, debuglevel):
        global gCallbackData
        if (debuglevel >= 1):
            print "DEBUG: gCallbackData is: %s on port: %s" % (gCallbackData, port)
        gCallbackData = ''
        self.ip = ip
        self.port = port
        self.connected = False
        self.debug = debuglevel
        if (self.debug >= 3):
            print "Creating server with " + str(ip) + ":" + str(port)
        self.server = myServer((ip, port), self.myhandler)
        self.server_thread = Thread(target=self.server.serve_forever)
        self.server_thread.setDaemon(True)
        self.server_thread.start()

    def disconnect(self, step=60, timeout=600):
        t = 0
        if (self.debug >= 3):
            print "Calling disconnect on callback server"
        while t < timeout:
            if (gCallbackData):
                # Got the data back
                if (self.debug >= 3):
                    print "Got data back from agent: " + str(gCallbackData)
                break
            else:
                if (self.debug >= 0):
                    print '.',
            time.sleep(step)
            t += step

        try:
            if (self.debug >= 3):
                print "Shutting down server now"
            self.server.shutdown()
        except:
            if (self.debug >= 1):
                print "Automation Error: Unable to shutdown callback server - check for a connection on port: " + str(self.port)

        # sleep 1 additional step to ensure not only we are online, but all our
        # services are online
        time.sleep(step)
        return gCallbackData

    class myhandler(SocketServer.BaseRequestHandler):
        def handle(self):
            global gCallbackData
            gCallbackData = self.request.recv(1024)
            # print "Callback Handler got data: " + str(gCallbackData)
            self.request.send("OK")
