#!/usr/bin/python
'''
Copyright (C) 2012  Diego Torres Milano
Created on Feb 3, 2012

@author: diego
'''

__version__ = '8.3.3'

import sys
import os
import getopt

try:
    sys.path.insert(0, os.path.join(os.environ['ANDROID_VIEW_CLIENT_HOME'], 'src'))
except:
    pass

from com.dtmilano.android.viewclient import ViewClient

HELP = 'help'
VERBOSE = 'verbose'
VERSION = 'version'
IGNORE_SECURE_DEVICE = 'ignore-secure-device'
IGNORE_VERSION_CHECK = 'ignore-version-check'
FORCE_VIEW_SERVER_USE = 'force-view-server-use'
DO_NOT_START_VIEW_SERVER = 'do-not-start-view-server'
DO_NOT_IGNORE_UIAUTOMATOR_KILLED = 'do-not-ignore-uiautomator-killed'
WINDOW = 'window'
UNIQUE_ID = 'uniqueId'
POSITION = 'position'
CONTENT_DESCRIPTION = 'content-description'
CENTER = 'center'
SAVE_SCREENSHOT = 'save-screenshot'
SAVE_VIEW_SCREENSHOTS = 'save-view-screenshots'

def traverseSaveViewScreenshots(view):
    dir = options[SAVE_VIEW_SCREENSHOTS]
    var = view.variableNameFromId()
    filename = '%s/%s.png' % (dir, var)
    if kwargs1[VERBOSE]:
        print view.__tinyStr__(), ' => ', filename
    view.writeImageToFile(filename)

MAP = {'i':ViewClient.TRAVERSE_CITUI, UNIQUE_ID:ViewClient.TRAVERSE_CITUI,
       'x':ViewClient.TRAVERSE_CITPS, POSITION:ViewClient.TRAVERSE_CITPS,
       'd':ViewClient.TRAVERSE_CITCD, CONTENT_DESCRIPTION:ViewClient.TRAVERSE_CITCD,
       'c':ViewClient.TRAVERSE_CITC, CENTER:ViewClient.TRAVERSE_CITC,
       'W':traverseSaveViewScreenshots, SAVE_VIEW_SCREENSHOTS:traverseSaveViewScreenshots,
       }

USAGE = 'usage: %s [OPTION]... [serialno]'
SHORT_OPTS = 'HVvIEFSkw:ixdcs:W:'
LONG_OPTS =  [HELP, VERBOSE, VERSION, IGNORE_SECURE_DEVICE, IGNORE_VERSION_CHECK, FORCE_VIEW_SERVER_USE,
              DO_NOT_START_VIEW_SERVER, DO_NOT_IGNORE_UIAUTOMATOR_KILLED, WINDOW + '=',
              UNIQUE_ID, POSITION, CONTENT_DESCRIPTION, CENTER,
              SAVE_SCREENSHOT + '=', SAVE_VIEW_SCREENSHOTS + '=',
              ]
LONG_OPTS_ARG = {WINDOW: 'WINDOW', SAVE_SCREENSHOT: 'FILE', SAVE_VIEW_SCREENSHOTS: 'DIR'}
OPTS_HELP = {
    'H': 'prints this help',
    'V': 'verbose comments',
    'I': 'ignore secure device',
    'F': 'force view server use (even if UiAutomator present)',
    'S': 'don\'t start ViewServer',
    'k': 'don\'t ignore UiAutomator killed',
    'w': 'dump WINDOW content (default: -1, all windows)',
    'i': 'dump View unique IDs',
    'x': 'dump View positions',
    'd': 'dump View content descriptions',
    'c': 'dump View centers',
    's': 'save screenshot to file',
    'W': 'save View screenshots to files in directory',
    'E': 'ignores ADB version check'
    }

def shortAndLongOptions():
    '''
    @return: the list of corresponding (short-option, long-option) tuples
    '''

    short_opts = SHORT_OPTS.replace(':', '')
    if len(short_opts) != len(LONG_OPTS):
        raise Exception('There is a mismatch between short and long options')
    t = tuple(short_opts) + tuple(LONG_OPTS)
    l2 = len(t)/2
    sl = []
    for i in range(l2):
        sl.append((t[i], t[i+l2]))
    return sl

def usage(exitVal=1):
    print >> sys.stderr, USAGE % progname
    print >> sys.stderr, "Try '%s --help' for more information." % progname
    sys.exit(exitVal)

def help():
    print >> sys.stderr, USAGE % progname
    print >> sys.stderr
    print >> sys.stderr, "Options:"
    for so, lo in shortAndLongOptions():
        o = '  -%c, --%s' % (so, lo)
        if lo[-1] == '=':
            o += LONG_OPTS_ARG[lo[:-1]]
        try:
            o = '%-34s %-45s' % (o, OPTS_HELP[so])
        except:
            pass
        print >> sys.stderr, o
    sys.exit(0)

def version():
    print progname, __version__
    sys.exit(0)

# __main__
progname = os.path.basename(sys.argv[0])
try:
    opts, args = getopt.getopt(sys.argv[1:], SHORT_OPTS, LONG_OPTS)
    sys.argv[1:] = args
except getopt.GetoptError, e:
    print >>sys.stderr, 'ERROR:', str(e)
    usage()

kwargs1 = {VERBOSE: False, 'ignoresecuredevice': False, 'ignoreversioncheck': False}
kwargs2 = {'forceviewserveruse': False, 'startviewserver': True, 'autodump': False, 'ignoreuiautomatorkilled': True}
options = {WINDOW: -1, SAVE_SCREENSHOT: None, SAVE_VIEW_SCREENSHOTS: None}
transform = ViewClient.TRAVERSE_CIT
for o, a in opts:
    o = o.strip('-')
    if o in ['H', HELP]:
        help()
    elif o in ['V', VERBOSE]:
        kwargs1[VERBOSE] = True
    elif o in ['v', VERSION]:
        version()
    elif o in ['I', IGNORE_SECURE_DEVICE]:
        kwargs1['ignoresecuredevice'] = True
    elif o in ['E', IGNORE_VERSION_CHECK]:
        kwargs1['ignoreversioncheck'] = True
    elif o in ['F', FORCE_VIEW_SERVER_USE]:
        kwargs2['forceviewserveruse'] = True
    elif o in ['S', DO_NOT_START_VIEW_SERVER]:
        kwargs2['startviewserver'] = False
    elif o in ['k', DO_NOT_IGNORE_UIAUTOMATOR_KILLED]:
        kwargs2['ignoreuiautomatorkilled'] = False
    elif o in ['w', WINDOW]:
        options[WINDOW] = a
    elif o in ['s', SAVE_SCREENSHOT]:
        options[SAVE_SCREENSHOT] = a
    elif o in ['W', SAVE_VIEW_SCREENSHOTS]:
        options[SAVE_VIEW_SCREENSHOTS] = a
        transform = MAP[o]
    else:
        transform = MAP[o]

vc = ViewClient(*ViewClient.connectToDeviceOrExit(**kwargs1), **kwargs2)
vc.dump(window=options[WINDOW])
if options[SAVE_SCREENSHOT]:
    vc.writeImageToFile(options[SAVE_SCREENSHOT])
vc.traverse(transform=transform)
