# 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/.

"""
Command-line client to control a device
"""

import errno
import logging
import os
import posixpath
import StringIO
import sys
import mozdevice
import mozlog
import argparse

class DMCli(object):

    def __init__(self):
        self.commands = { 'deviceroot': { 'function': self.deviceroot,
                                          'help': 'get device root directory for storing temporary files' },
                          'install': { 'function': self.install,
                                       'args': [ { 'name': 'file' } ],
                                       'help': 'push this package file to the device and install it' },
                          'uninstall': { 'function': self.uninstall,
                                         'args': [ { 'name': 'packagename' } ],
                                         'help': 'uninstall the named app from the device' },
                          'killapp': { 'function': self.kill,
                                       'args': [ { 'name': 'process_name', 'nargs': '*' } ],
                                       'help': 'kills any processes with name(s) on device' },
                          'launchapp': { 'function': self.launchapp,
                                         'args': [ { 'name': 'appname' },
                                                   { 'name': 'activity_name' },
                                                   { 'name': '--intent',
                                                     'action': 'store',
                                                     'default': 'android.intent.action.VIEW' },
                                                   { 'name': '--url',
                                                     'action': 'store' },
                                                   { 'name': '--no-fail-if-running',
                                                     'action': 'store_true',
                                                     'help': 'Don\'t fail if application is already running' }
                                                ],
                                      'help': 'launches application on device' },
                          'listapps': { 'function': self.listapps,
                                        'help': 'list applications on device' },
                          'push': { 'function': self.push,
                                    'args': [ { 'name': 'local_file' },
                                              { 'name': 'remote_file' }
                                              ],
                                    'help': 'copy file/dir to device' },
                          'pull': { 'function': self.pull,
                                    'args': [ { 'name': 'local_file' },
                                              { 'name': 'remote_file', 'nargs': '?' } ],
                                    'help': 'copy file/dir from device' },
                          'shell': { 'function': self.shell,
                                    'args': [ { 'name': 'command', 'nargs': argparse.REMAINDER },
                                              { 'name': '--root', 'action': 'store_true',
                                                'help': 'Run command as root' }],
                                    'help': 'run shell command on device' },
                          'info': { 'function': self.getinfo,
                                    'args': [ { 'name': 'directive', 'nargs': '?' } ],
                                    'help': 'get information on specified '
                                    'aspect of the device (if no argument '
                                    'given, print all available information)'
                                    },
                          'ps': { 'function': self.processlist,
                                  'help': 'get information on running processes on device'
                                },
                          'logcat' : { 'function': self.logcat,
                                       'help': 'get logcat from device'
                                },
                          'ls': { 'function': self.listfiles,
                                  'args': [ { 'name': 'remote_dir' } ],
                                  'help': 'list files on device'
                                },
                          'rm': { 'function': self.removefile,
                                  'args': [ { 'name': 'remote_file' } ],
                                  'help': 'remove file from device'
                                },
                          'isdir': { 'function': self.isdir,
                                     'args': [ { 'name': 'remote_dir' } ],
                                     'help': 'print if remote file is a directory'
                                },
                          'mkdir': { 'function': self.mkdir,
                                     'args': [ { 'name': 'remote_dir' } ],
                                     'help': 'makes a directory on device'
                                },
                          'rmdir': { 'function': self.rmdir,
                                     'args': [ { 'name': 'remote_dir' } ],
                                     'help': 'recursively remove directory from device'
                                },
                          'screencap': { 'function': self.screencap,
                                         'args': [ { 'name': 'png_file' } ],
                                         'help': 'capture screenshot of device in action'
                                         },
                          'sutver': { 'function': self.sutver,
                                      'help': 'SUTAgent\'s product name and version (SUT only)'
                                   },
                          'clearlogcat': { 'function': self.clearlogcat,
                                           'help': 'clear the logcat'
                                         },
                          'reboot': { 'function': self.reboot,
                                      'help': 'reboot the device',
                                      'args': [ { 'name': '--wait',
                                                  'action': 'store_true',
                                                  'help': 'Wait for device to come back up before exiting' } ]

                                   },
                          'isfile': { 'function': self.isfile,
                                      'args': [ { 'name': 'remote_file' } ],
                                      'help': 'check whether a file exists on the device'
                                   },
                          'launchfennec': { 'function': self.launchfennec,
                                            'args': [ { 'name': 'appname' },
                                                      { 'name': '--intent', 'action': 'store',
                                                        'default': 'android.intent.action.VIEW' },
                                                      { 'name': '--url', 'action': 'store' },
                                                      { 'name': '--extra-args', 'action': 'store' },
                                                      { 'name': '--mozenv', 'action': 'store',
                                                        'help': 'Gecko environment variables to set in "KEY1=VAL1 KEY2=VAL2" format' },
                                                      { 'name': '--no-fail-if-running',
                                                        'action': 'store_true',
                                                        'help': 'Don\'t fail if application is already running' }
                                                      ],
                                            'help': 'launch fennec'
                                            },
                          'getip': { 'function': self.getip,
                                     'args': [ { 'name': 'interface', 'nargs': '*' } ],
                                     'help': 'get the ip address of the device'
                                   }
                          }

        self.parser = argparse.ArgumentParser()
        self.add_options(self.parser)
        self.add_commands(self.parser)
        mozlog.commandline.add_logging_group(self.parser)

    def run(self, args=sys.argv[1:]):
        args = self.parser.parse_args()

        mozlog.commandline.setup_logging(
            'mozdevice', args, {'mach': sys.stdout})

        if args.dmtype == "sut" and not args.host and not args.hwid:
            self.parser.error("Must specify device ip in TEST_DEVICE or "
                              "with --host option with SUT")

        self.dm = self.getDevice(dmtype=args.dmtype, hwid=args.hwid,
                                 host=args.host, port=args.port,
                                 verbose=args.verbose)

        ret = args.func(args)
        if ret is None:
            ret = 0

        sys.exit(ret)

    def add_options(self, parser):
        parser.add_argument("-v", "--verbose", action="store_true",
                            help="Verbose output from DeviceManager",
                            default=bool(os.environ.get('VERBOSE')))
        parser.add_argument("--host", action="store",
                            help="Device hostname (only if using TCP/IP, " \
                                "defaults to TEST_DEVICE environment " \
                                "variable if present)",
                            default=os.environ.get('TEST_DEVICE'))
        parser.add_argument("-p", "--port", action="store",
                            type=int,
                            help="Custom device port (if using SUTAgent or "
                            "adb-over-tcp)", default=None)
        parser.add_argument("-m", "--dmtype", action="store",
                            help="DeviceManager type (adb or sut, defaults " \
                                "to DM_TRANS environment variable, if " \
                                "present, or adb)",
                            default=os.environ.get('DM_TRANS', 'adb'))
        parser.add_argument("-d", "--hwid", action="store",
                            help="HWID", default=None)
        parser.add_argument("--package-name", action="store",
                            help="Packagename (if using DeviceManagerADB)",
                            default=None)

    def add_commands(self, parser):
        subparsers = parser.add_subparsers(title="Commands", metavar="<command>")
        for (commandname, commandprops) in sorted(self.commands.iteritems()):
            subparser = subparsers.add_parser(commandname, help=commandprops['help'])
            if commandprops.get('args'):
                for arg in commandprops['args']:
                    # this is more elegant but doesn't work in python 2.6
                    # (which we still use on tbpl @ mozilla where we install
                    # this package)
                    # kwargs = { k: v for k,v in arg.items() if k is not 'name' }
                    kwargs = {}
                    for (k, v) in arg.items():
                        if k is not 'name':
                            kwargs[k] = v
                    subparser.add_argument(arg['name'], **kwargs)
            subparser.set_defaults(func=commandprops['function'])

    def getDevice(self, dmtype="adb", hwid=None, host=None, port=None,
                  packagename=None, verbose=False):
        '''
        Returns a device with the specified parameters
        '''
        logLevel = logging.ERROR
        if verbose:
            logLevel = logging.DEBUG

        if hwid:
            return mozdevice.DroidConnectByHWID(hwid, logLevel=logLevel)

        if dmtype == "adb":
            if host and not port:
                port = 5555
            return mozdevice.DroidADB(packageName=packagename,
                                      host=host, port=port,
                                      logLevel=logLevel)
        elif dmtype == "sut":
            if not host:
                self.parser.error("Must specify host with SUT!")
            if not port:
                port = 20701
            return mozdevice.DroidSUT(host=host, port=port,
                                      logLevel=logLevel)
        else:
            self.parser.error("Unknown device manager type: %s" % type)

    def deviceroot(self, args):
        print self.dm.deviceRoot

    def push(self, args):
        (src, dest) = (args.local_file, args.remote_file)
        if os.path.isdir(src):
            self.dm.pushDir(src, dest)
        else:
            dest_is_dir = dest[-1] == '/' or self.dm.dirExists(dest)
            dest = posixpath.normpath(dest)
            if dest_is_dir:
                dest = posixpath.join(dest, os.path.basename(src))
            self.dm.pushFile(src, dest)

    def pull(self, args):
        (src, dest) = (args.local_file, args.remote_file)
        if not self.dm.fileExists(src):
            print 'No such file or directory'
            return
        if not dest:
            dest = posixpath.basename(src)
        if self.dm.dirExists(src):
            self.dm.getDirectory(src, dest)
        else:
            self.dm.getFile(src, dest)

    def install(self, args):
        basename = os.path.basename(args.file)
        app_path_on_device = posixpath.join(self.dm.deviceRoot,
                                            basename)
        self.dm.pushFile(args.file, app_path_on_device)
        self.dm.installApp(app_path_on_device)

    def uninstall(self, args):
        self.dm.uninstallApp(args.packagename)

    def launchapp(self, args):
        self.dm.launchApplication(args.appname, args.activity_name,
                                  args.intent, url=args.url,
                                  failIfRunning=(not args.no_fail_if_running))

    def listapps(self, args):
        for app in self.dm.getInstalledApps():
            print app

    def stopapp(self, args):
        self.dm.stopApplication(args.appname)

    def kill(self, args):
        for name in args.process_name:
            self.dm.killProcess(name)

    def shell(self, args):
        buf = StringIO.StringIO()
        self.dm.shell(args.command, buf, root=args.root)
        print str(buf.getvalue()[0:-1]).rstrip()

    def getinfo(self, args):
        info = self.dm.getInfo(directive=args.directive)
        for (infokey, infoitem) in sorted(info.iteritems()):
            if infokey == "process":
                pass  # skip process list: get that through ps
            elif args.directive is None:
                print "%s: %s" % (infokey.upper(), infoitem)
            else:
                print infoitem

    def logcat(self, args):
        print ''.join(self.dm.getLogcat())

    def clearlogcat(self, args):
        self.dm.recordLogcat()

    def reboot(self, args):
        self.dm.reboot(wait=args.wait)

    def processlist(self, args):
        pslist = self.dm.getProcessList()
        for ps in pslist:
            print " ".join(str(i) for i in ps)

    def listfiles(self, args):
        filelist = self.dm.listFiles(args.remote_dir)
        for file in filelist:
            print file

    def removefile(self, args):
        self.dm.removeFile(args.remote_file)

    def isdir(self, args):
        if self.dm.dirExists(args.remote_dir):
            print "TRUE"
            return

        print "FALSE"
        return errno.ENOTDIR

    def mkdir(self, args):
        self.dm.mkDir(args.remote_dir)

    def rmdir(self, args):
        self.dm.removeDir(args.remote_dir)

    def screencap(self, args):
        self.dm.saveScreenshot(args.png_file)

    def sutver(self, args):
        if args.dmtype == 'sut':
            print '%s Version %s' % (self.dm.agentProductName,
                                     self.dm.agentVersion)
        else:
            print 'Must use SUT transport to get SUT version.'

    def isfile(self, args):
        if self.dm.fileExists(args.remote_file):
            print "TRUE"
            return
        print "FALSE"
        return errno.ENOENT

    def launchfennec(self, args):
        mozEnv = None
        if args.mozenv:
            mozEnv = {}
            keyvals = args.mozenv.split()
            for keyval in keyvals:
                (key, _, val) = keyval.partition("=")
                mozEnv[key] = val
        self.dm.launchFennec(args.appname, intent=args.intent,
                             mozEnv=mozEnv,
                             extraArgs=args.extra_args, url=args.url,
                             failIfRunning=(not args.no_fail_if_running))

    def getip(self, args):
        if args.interface:
            print(self.dm.getIP(args.interface))
        else:
            print(self.dm.getIP())

def cli(args=sys.argv[1:]):
    # process the command line
    cli = DMCli()
    cli.run(args)

if __name__ == '__main__':
    cli()
