#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
Copyright (C) 2013-2016  Diego Torres Milano
Created on Mar 28, 2013

Culebra helps you create AndroidViewClient scripts generating a working template that can be
modified to suit more specific needs.
                      __    __    __    __
                     /  \  /  \  /  \  /  \ 
____________________/  __\/  __\/  __\/  __\_____________________________
___________________/  /__/  /__/  /__/  /________________________________
                   | / \   / \   / \   / \   \___
                   |/   \_/   \_/   \_/   \    o \ 
                                           \_____/--<

@author: Diego Torres Milano
@author: Jennifer E. Swofford (ascii art snake)


''' 

__version__ = '11.5.9'

import re
import sys
import os
import getopt
import warnings
import subprocess
import codecs
import calendar
from datetime import date

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

from com.dtmilano.android.viewclient import ViewClient, ViewClientOptions, View, CulebraOptions
from com.dtmilano.android.culebron import Culebron, Operation, Unit

DEBUG = False
USAGE = 'usage: %s [OPTION]... [serialno]'
TAG = 'CULEBRA'

class Descriptor:
    CONTENT_DESCRIPTION = 'content-description'
    TEXT = 'text'
    ID = 'id'

    @staticmethod
    def findBestDescriptor(view):
        '''
        Finds the best possible descriptor for the View
        '''
        
        cd = view.getContentDescription()
        if cd and options[CulebraOptions.FIND_VIEWS_WITH_CONTENT_DESCRIPTION]:
            return Descriptor.CONTENT_DESCRIPTION
        else:
            t = view.getText()
            if t and options[CulebraOptions.FIND_VIEWS_WITH_TEXT]:
                return Descriptor.TEXT
        return Descriptor.ID
    

def fillAutoRegexpsRes():
    are = {}
    are['clock'] = re.compile('[012]?\d:[0-5]\d')
    d = "("
    for i in range(7):
        d += calendar.day_abbr[i]
        if i != 6:
            d += '|'
    d += '), ('
    for i in range(1, 13):
        d += calendar.month_name[i]
        if i != 12:
            d += '|'
    d += ') [0123]\d'
    are['date'] = re.compile(d, re.IGNORECASE)
    are['battery'] = re.compile('Charging, \d\d%')
    return are

CulebraOptions.AUTO_REGEXPS_RES = fillAutoRegexpsRes()
SB_NO_JAR = 'no-jar'
SB_JAR = 'jar'
SB_JAR_LINUX = 'jar-linux'
SHEBANG = {
    SB_NO_JAR: '#! /usr/bin/env python',
    SB_JAR: '#! /usr/bin/env shebang monkeyrunner -plugin $ANDROID_VIEW_CLIENT_HOME/bin/androidviewclient-$ANDROID_VIEW_CLIENT_VERSION.jar @!',
    SB_JAR_LINUX: '#! /usr/local/bin/shebang monkeyrunner -plugin $AVC_HOME/bin/androidviewclient-$AVC_VERSION.jar @!'
    }

indent = ''
prefix = ''

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

    short_opts = CulebraOptions.SHORT_OPTS.replace(':', '')
    if len(short_opts) != len(CulebraOptions.LONG_OPTS):
        s = ""
        for i in range(max(len(short_opts), len(CulebraOptions.LONG_OPTS))):
            l = ''
            try:
                l = short_opts[i]
            except IndexError:
                pass
            L = ''
            try:
                L = CulebraOptions.LONG_OPTS[i]
            except IndexError:
                pass
            s += "%3s - %s\n" % (l, L)
        raise Exception('There is a mismatch between short and long options: short=%d, long=%d\n%s' %
                        (len(short_opts), len(CulebraOptions.LONG_OPTS), s))
    t = tuple(short_opts) + tuple(CulebraOptions.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 += CulebraOptions.LONG_OPTS_ARG[lo[:-1]]
        try:
            o = '%-34s %-45s' % (o, CulebraOptions.OPTS_HELP[so])
        except:
            pass
        print >> sys.stderr, o
    sys.exit(0)

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

def autoRegexpsHelp():
    print >> sys.stderr, "Available %s options:" % CulebraOptions.AUTO_REGEXPS
    print >> sys.stderr, "\thelp: prints this help"
    print >> sys.stderr, "\tall: includes all the available regexps"
    for r in CulebraOptions.AUTO_REGEXPS_RES:
        print >> sys.stderr, "\t%s: %s" % (r, CulebraOptions.AUTO_REGEXPS_RES[r].pattern)
    print >> sys.stderr
    sys.exit(0)

def error(msg, fatal=False):
    print >> sys.stderr, "%s: ERROR: %s" % (progname, msg)
    if fatal:
        sys.exit(1)

def notNull(val, default):
    if val:
        return val
    return default

def printVerboseComments(view):
    '''
    Prints the verbose comments for view.
    '''

    print '\n%s# class=%s' % (indent, view.getClass()),
    try:
        text = view.getText()
        if text:
            u = 'u' if isinstance(text, unicode) else ''
            if '\n' in text:
                text = re.sub(r'\n(.)', r'\n#\1', text)
            print " text=%c'%s'" % (u, text),
    except:
        pass
    try:
        contentDescription = view.getContentDescription()
        if contentDescription:
            print u" cd='%s'" % contentDescription,
    except:
        pass
    try:
        tag = view.getTag()
        if tag and tag != 'null':
            print ' tag=%s' % tag,
    except:
        pass
    print

def variableNameFromIdOrKey(view):
    '''
    Returns a suitable variable name from the id.

    @type view: L{View}
    @param id: the View from where the I{uniqueId} is obtained

    @return: the variable name from the id
    '''

    var = view.variableNameFromId()
    if options[CulebraOptions.USE_DICTIONARY]:
        return '%sviews[\'%s\']' % (prefix, notNull(dictionaryKeyFrom(options[CulebraOptions.DICTIONARY_KEYS_FROM], view), var))
    else:
        return var

def dictionaryKeyFrom(key, view):
    if key == 'id':
        return view.getUniqueId()
    elif key == 'text':
        return view.getText()
    elif key == 'content-description':
        return view.getContentDescription()
    else:
        raise Exception('Not a valid dictionary key: %s' % key)

def escapeRegexpSpecialChars(text):
    return re.escape(text)

def printFindViewWithText(view, useregexp, op=Operation.ASSIGN, arg=None):
    '''
    Prints the corresponding statement.

    @type view: L{View}
    @param view: the View
    '''

    text = view.getText()
    isUnicode = isinstance(text, unicode)
    if isUnicode and sys.stdout.encoding is None:
        warnings.warn('''\
You are trying to print unicode characters to an unencoded stdout, it will probably fail.
You have to set PYTHONIOENCODING environment variable. For example:
       export PYTHONIOENCODING=utf-8
        ''')

    u = 'u' if isUnicode else ''
    if text:
        var = variableNameFromIdOrKey(view)
        if text.find(u"\n") > 0 or text.find(u"'") > 0:
            # 2 quotes + 1 quote = 3 quotes
            text = "''%s''" % text
        if useregexp:
            # if there are special chars already in the text escape them
            text = escapeRegexpSpecialChars(text)
            if options[CulebraOptions.AUTO_REGEXPS]:
                for r in options[CulebraOptions.AUTO_REGEXPS]:
                    autoRegexp = CulebraOptions.AUTO_REGEXPS_RES[r]
                    if autoRegexp.match(text):
                        text = autoRegexp.pattern
                        break
            text = "re.compile(%s'%s')" % (u, text)
        else:
            text = "%s'%s'" % (u, text)
            
        if op == Operation.ASSIGN:
            if options[CulebraOptions.MULTI_DEVICE]:
                warnings.warn('Multi-device not implemented yet for this case')
            else:
                logAction(u'finding view with text=%s' % text)
                print u'%s%s = %svc.findViewWithTextOrRaise(%s)' % (indent, var, prefix, text)
        elif op == Operation.LONG_TOUCH_VIEW:
            root = ', root=%svc.findViewByIdOrRaise(\'%s\')' % (prefix, arg.getUniqueId()) if arg else ''
            if options[CulebraOptions.MULTI_DEVICE]:
                logAction(u'long touch view with text=%s on ${serialno}' % text)
                print u'%s[_vc.findViewWithTextOrRaise(%s%s).longTouch() for _vc in %sallVcs()]' % (indent, text, root, prefix)
            else:
                logAction(u'long touch view with text=%s' % text)
                print u'%s%svc.findViewWithTextOrRaise(%s%s).longTouch()' % (indent, prefix, text, root)
        elif op == Operation.TOUCH_VIEW:
            root = ', root=%svc.findViewByIdOrRaise(\'%s\')' % (prefix, arg.getUniqueId()) if arg else ''
            if options[CulebraOptions.MULTI_DEVICE]:
                logAction(u'touching view with text=%s on ${serialno}' % text)
                print u'%s[_vc.findViewWithTextOrRaise(%s%s).touch() for _vc in %sallVcs()]' % (indent, text, root, prefix)
            else:
                logAction(u'touching view with text=%s' % text)
                print u'%s%svc.findViewWithTextOrRaise(%s%s).touch()' % (indent, prefix, text, root)
        elif op == Operation.TYPE:
            if options[CulebraOptions.MULTI_DEVICE]:
                warnings.warn('Multi-device not implemented yet for this case')
            else:
                print '%s%svc.findViewWithTextOrRaise("%s").type(u"%s")' % (indent, prefix, text, arg)
        elif op == Operation.SET_TEXT:
            if options[CulebraOptions.MULTI_DEVICE]:
                warnings.warn('Multi-device not implemented yet for this case')
            else:
                print '%s%svc.findViewWithTextOrRaise(%s).setText(u"%s")' % (indent, prefix, text, arg)
        elif op in [Operation.FLING_BACKWARD, Operation.FLING_FORWARD, Operation.FLING_TO_BEGINNING, Operation.FLING_TO_END]:
            if options[CulebraOptions.MULTI_DEVICE]:
                warnings.warn('Multi-device not implemented yet for this case')
            else:
                commandName = Operation.toCommandName(op)
                logAction(u'flinging view with text=%s %s' % (text, commandName))
                print u'%s%svc.findViewWithTextOrRaise(%s).uiScrollable.%s()' % (indent, prefix, text, commandName)
        elif op == Operation.TEST:
            if options[CulebraOptions.MULTI_DEVICE]:
                warnings.warn('Multi-device not implemented yet for this case')
            else:
                print '%s%sassertIsNotNone(%svc.findViewWithText(%s))' % (indent, prefix, prefix, text)
    elif kwargs1[CulebraOptions.VERBOSE]:
        warnings.warn('View with id=%s has no text' % view.getUniqueId())

def printFindViewWithContentDescription(view, useregexp, op=Operation.ASSIGN, arg=None):
    '''
    Prints the corresponding statement.

    @type view: L{View}
    @param view: the View
    '''

    contentDescription = view.getContentDescription()
    if contentDescription:
        var = variableNameFromIdOrKey(view)
        if useregexp:
            if options[CulebraOptions.AUTO_REGEXPS]:
                for r in options[CulebraOptions.AUTO_REGEXPS]:
                    autoRegexp = CulebraOptions.AUTO_REGEXPS_RES[r]
                    if autoRegexp.match(contentDescription):
                        contentDescription = autoRegexp.pattern
                        break
            contentDescription = "re.compile(u'''%s''')" % contentDescription
        else:
            contentDescription = "u'''%s'''" % contentDescription
        
        if op == Operation.ASSIGN:
            if options[CulebraOptions.MULTI_DEVICE]:
                warnings.warn('Multi-device not implemented yet for this case')
            else:
                logAction(u'finding view with content-description=%s' % contentDescription)
                print '%s%s = %svc.findViewWithContentDescriptionOrRaise(%s)' % (indent, var, prefix, contentDescription)
        elif op == Operation.LONG_TOUCH_VIEW:
            if options[CulebraOptions.MULTI_DEVICE]:
                logAction(u'long touch view with content-description=%s on ${serialno}' % contentDescription)
                # print u'%s[_vc.findViewWithTextOrRaise(%s).touch() for _vc in %sallVcs()]' % (indent, text, root)
                print u'%s[_vc.findViewWithContentDescriptionOrRaise(%s).longTouch() for _vc in %sallVcs()]' % (indent, contentDescription, prefix)
            else:
                logAction(u'long touch view with content-description=%s' % contentDescription)
                print u'%s%svc.findViewWithContentDescriptionOrRaise(%s).longTouch()' % (indent, prefix, contentDescription)
        elif op == Operation.TOUCH_VIEW:
            if options[CulebraOptions.MULTI_DEVICE]:
                logAction(u'touching view with content-description=%s on ${serialno}' % contentDescription)
                # print u'%s[_vc.findViewWithTextOrRaise(%s).touch() for _vc in %sallVcs()]' % (indent, text, root)
                print u'%s[_vc.findViewWithContentDescriptionOrRaise(%s).touch() for _vc in %sallVcs()]' % (indent, contentDescription, prefix)
            else:
                logAction(u'touching view with content-description=%s' % contentDescription)
                print u'%s%svc.findViewWithContentDescriptionOrRaise(%s).touch()' % (indent, prefix, contentDescription)
        elif op == Operation.TYPE:
            if options[CulebraOptions.MULTI_DEVICE]:
                warnings.warn('Multi-device not implemented yet for this case')
            else:
                print '%s%svc.findViewWithContentDescriptionOrRaise(%s).type(u"%s")' % (indent, prefix, contentDescription, arg)
        elif op == Operation.SET_TEXT:
            if options[CulebraOptions.MULTI_DEVICE]:
                warnings.warn('Multi-device not implemented yet for this case')
            else:
                print '%s%svc.findViewWithContentDescriptionOrRaise(%s).setText(u"%s")' % (indent, prefix, contentDescription, arg)
        elif op == Operation.TEST:
            if options[CulebraOptions.MULTI_DEVICE]:
                warnings.warn('Multi-device not implemented yet for this case')
            else:
                print '%s%sassertEquals(%svc.findViewWithContentDescriptionOrRaise(%s).getText(), u\'\'\'%s\'\'\')' % (indent, prefix, prefix, contentDescription, arg)
        elif op in [Operation.FLING_BACKWARD, Operation.FLING_FORWARD, Operation.FLING_TO_BEGINNING, Operation.FLING_TO_END]:
            if options[CulebraOptions.MULTI_DEVICE]:
                warnings.warn('Multi-device not implemented yet for this case')
            else:
                commandName = Operation.toCommandName(op)
                logAction(u'flinging view with content-description=%s %s' % (contentDescription, commandName))
                print u'%s%svc.findViewWithContentDescriptionOrRaise(%s).uiScrollable.%s()' % (indent, prefix, contentDescription, commandName)
        else:
            error("Invalid operation in %s: %s" % (sys._getframe().f_code.co_name), op)
            
    elif kwargs1[CulebraOptions.VERBOSE]:
        warnings.warn('View with id=%s has no content-description' % view.getUniqueId())

def printFindViewById(view, op=Operation.ASSIGN, arg=None):
    '''
    Prints the corresponding statement.

    @type view: L{View}
    @param view: the View
    '''

    var = variableNameFromIdOrKey(view)
    _id = view.getId() if view.getId() else view.getUniqueId()
    if op == Operation.ASSIGN:
        if options[CulebraOptions.MULTI_DEVICE]:
            logAction('finding view with id=%s on ${serialno}' % _id)
            print '%s%s = [_vc.findViewByIdOrRaise("%s") for _vc in %sallVcs()]' % (indent, var, _id, prefix)
        else:
            logAction('finding view with id=%s' % _id)
            print '%s%s = %svc.findViewByIdOrRaise("%s")' % (indent, var, prefix, _id)
    elif op == Operation.LONG_TOUCH_VIEW:
        if options[CulebraOptions.MULTI_DEVICE]:
            logAction(u'long touch view with id=%s on ${serialno}' % _id)
            print '%s[_vc.findViewByIdOrRaise("%s").longTouch() for _vc in %sallVcs()]' % (indent, _id, prefix)
        else:
            logAction(u'long touch view with id=%s' % _id)
            print '%s%svc.findViewByIdOrRaise("%s").longTouch()' % (indent, prefix, _id)
    elif op == Operation.TOUCH_VIEW:
        if options[CulebraOptions.MULTI_DEVICE]:
            logAction(u'touching view with id=%s on ${serialno}' % _id)
            print '%s[_vc.findViewByIdOrRaise("%s").touch() for _vc in %sallVcs()]' % (indent, _id, prefix)
        else:
            logAction(u'touching view with id=%s' % _id)
            print '%s%svc.findViewByIdOrRaise("%s").touch()' % (indent, prefix, _id)
    elif op == Operation.TYPE:
        if options[CulebraOptions.MULTI_DEVICE]:
            warnings.warn('Multi-device not implemented yet for this case')
        else:
            logAction('typing "%s" on view with id=%s' % (arg, _id))
            print '%s%svc.findViewByIdOrRaise("%s").type(u"%s")' % (indent, prefix, _id, arg)
    elif op == Operation.SET_TEXT:
        if options[CulebraOptions.MULTI_DEVICE]:
            warnings.warn('Multi-device not implemented yet for this case')
        else:
            logAction('setting text "%s" on view with id=%s' % (arg, _id))
            print '%s%svc.findViewByIdOrRaise("%s").setText(u"%s")' % (indent, prefix, _id, arg)
    elif op == Operation.TEST:
        if options[CulebraOptions.MULTI_DEVICE]:
            warnings.warn('Multi-device not implemented yet for this case')
        else:
            print '%s%sassertEquals(%svc.findViewByIdOrRaise("%s").getText(), u\'\'\'%s\'\'\')' % (indent, prefix, prefix, _id, arg)
    elif op in [Operation.FLING_BACKWARD, Operation.FLING_FORWARD, Operation.FLING_TO_BEGINNING, Operation.FLING_TO_END]:
        if options[CulebraOptions.MULTI_DEVICE]:
            warnings.warn('Multi-device not implemented yet for this case')
        else:
            commandName = Operation.toCommandName(op)
            logAction(u'flinging view with id=%s %s' % (_id, commandName))
            print u'%s%svc.findViewWithIdOrRaise(u"%s").uiScrollable.%s()' % (indent, prefix, _id, commandName)
    else:
        error("Invalid operation in %s: %s" % (sys._getframe().f_code.co_name, op))


def printTraverse(dump=None):
    '''
    Prints the result of traversing the tree.
    A previously obtained dump can be passed as a parameter and in such case that
    tree is used.
    
    @param dump: Dump of Views previously obtained via L{ViewClient.dump()}
    @type dump: list
    '''
    
    print 
    if dump:
        for view in dump:
            transform(view)
    else:
        vc.traverse(transform=transform)
    print

def printDump(window, dump=None):
    '''
    Prints a dump.
    
    @param window: The window id to use to print the dump
    @type window: int or str
    @param dump: Dump of Views previously obtained via L{ViewClient.dump()}
    @type dump: list
    '''
    
    if options[CulebraOptions.MULTI_DEVICE]:
        logAction('dumping content of window=%s on ${serialno}' % window)
        print '%s[_vc.dump(window=%s) for _vc in %sallVcs()]' % (indent, window, prefix)
    else:
        logAction('dumping content of window=%s' % window)
        print '%s%svc.dump(window=%s)' % (indent, prefix, window)
    
    if not options[CulebraOptions.DO_NOT_VERIFY_SCREEN_DUMP]:
        printTraverse(dump)
    
def printSleep(secs):
    '''
    Prints a sleep.
    
    This method relies on shortcut variables being set (i.e. _s)
    '''
    
    if options[CulebraOptions.MULTI_DEVICE]:
        print '%s[_vc.sleep(%s) for _vc in %sallVcs()]' % (indent, secs if secs != Operation.DEFAULT else '_s', prefix)
    else:
        print '%s%svc.sleep(%s)' % (indent, prefix, secs if secs != Operation.DEFAULT else '_s')

def printWake():
    '''
    Prints a wake.

    :return:
    '''

    if options[CulebraOptions.MULTI_DEVICE]:
        print '%s[_vc.device.wake() for _vc in %sallVcs()]' % (indent, prefix)
    else:
        print '%s%svc.device.wake()' % (indent, prefix)

def printPress(keycode):
    '''
    Prints a key press
    '''
    
    if options[CulebraOptions.MULTI_DEVICE]:
        logAction(u'pressing key=%s on ${serialno}' % keycode)
        print '%s[_d.press(\'%s\') for _d in %sallDevices()]' % (indent, keycode, prefix)
    else:
        logAction(u'pressing key=%s' % keycode)
        print '%s%sdevice.press(\'%s\')' % (indent, prefix, keycode)
    
def printDrag(start, end, duration, steps, unit, orientation):
    '''
    Prints a drag
    '''
    
    if unit == Unit.PX:
        if options[CulebraOptions.MULTI_DEVICE]:
            warnings.warn('Multi-device not implemented yet for this case')
        else:
            print '%s%sdevice.drag(%s, %s, %d, %d, %d)' % (indent, prefix, start, end, duration, steps, orientation) 
    elif unit == Unit.DIP:
        if options[CulebraOptions.MULTI_DEVICE]:
            warnings.warn('Multi-device not implemented yet for this case')
        else:
            print '%s%sdevice.dragDip(%s, %s, %d, %d, %d)' % (indent, prefix, start, end, duration, steps, orientation) 
    else:
        raise RuntimeError('Invalid unit: %s' % unit)
    
def printTouch(x, y, unit, orientation):
    '''
    Prints a touch
    '''
    
    if unit == Unit.PX:
        if options[CulebraOptions.MULTI_DEVICE]:
            warnings.warn('Multi-device not implemented yet for this case')
        else:
            logAction(u'touching point by PX @ (%s, %s) orientation=%s' % (x, y, orientation))
            print '%s%sdevice.touch(%s, %s, %s)' % (indent, prefix, x, y, orientation)
    elif unit == Unit.DIP:
        if options[CulebraOptions.MULTI_DEVICE]:
            warnings.warn('Multi-device not implemented yet for this case')
        else:
            logAction(u'touching point by DIP @ (%s, %s) orientation=%s' % (x, y, orientation))
            print '%s%sdevice.touchDip(%s, %s, %s)' % (indent, prefix, x, y, orientation)
    else:
        raise RuntimeError('Invalid unit: %s' % unit)
    
def printLongTouch(x, y, duration, unit, orientation):
    '''
    Prints a long touch
    '''
    
    if unit == Unit.PX:
        if options[CulebraOptions.MULTI_DEVICE]:
            warnings.warn('Multi-device not implemented yet for this case')
        else:
            logAction(u'long touching point by PX @ (%s, %s) duration=%s orientation=%s' % (x, y, duration, orientation))
            print '%s%sdevice.longTouch(%s, %s, %s, %s)' % (indent, prefix, x, y, duration, orientation)
    elif unit == Unit.DIP:
        if options[CulebraOptions.MULTI_DEVICE]:
            warnings.warn('Multi-device not implemented yet for this case')
        else:
            logAction(u'long touching point by DIP @ (%s, %s) duration=%s orientation=%s' % (x, y, duration, orientation))
            print '%s%sdevice.longTouch(%s, %s, %s, %s)' % (indent, prefix, x, y, duration, orientation)
    else:
        raise RuntimeError('Invalid unit: %s' % unit)
    
def printSaveViewScreenshot(view, filename, _format):
    '''
    Prints the writeImageToFile for the specified L{View}.
    
    @type view: L{View}
    @param view: the View
    @type filename: str
    @param filename: the filename to store the image
    @type _format: str
    @param _format: The image format (i.e. PNG)
    '''

    if options[CulebraOptions.MULTI_DEVICE]:
        warnings.warn('Multi-device not implemented yet for this case')
    else:
        # FIXME: if -u was passed in the command line then we are not saving the variables and thus
        # next line will generate an error in the script as the variable is 'undefined'
        print '%s%s.writeImageToFile(\'%s\', \'%s\')' % (indent, view.variableNameFromId(), filename, _format)
    
def printFlingBackward(view):
    if options[CulebraOptions.MULTI_DEVICE]:
        warnings.warn('Multi-device not implemented yet for this case')
    else:
        # FIXME: if -u was passed in the command line then we are not saving the variables and thus
        # next line will generate an error in the script as the variable is 'undefined'
        logAction('flinging backward view with id=%s' % view.getId())
        print '%s%s.uiScrollable.flingBackward()' % (indent, view.variableNameFromId())
    
def printFlingForward(view):
    if options[CulebraOptions.MULTI_DEVICE]:
        warnings.warn('Multi-device not implemented yet for this case')
    else:
        # FIXME: if -u was passed in the command line then we are not saving the variables and thus
        # next line will generate an error in the script as the variable is 'undefined'
        logAction('flinging forward view with id=%s' % view.getId())
        print '%s%s.uiScrollable.flingForward()' % (indent, view.variableNameFromId())
    
def printFlingToBeginning(view):
    if options[CulebraOptions.MULTI_DEVICE]:
        warnings.warn('Multi-device not implemented yet for this case')
    else:
        # FIXME: if -u was passed in the command line then we are not saving the variables and thus
        # next line will generate an error in the script as the variable is 'undefined'
        logAction('flinging to beginning view with id=%s' % view.getId())
        print '%s%s.uiScrollable.flingToBeginning()' % (indent, view.variableNameFromId())
    
def printFlingToEnd(view):
    if options[CulebraOptions.MULTI_DEVICE]:
        warnings.warn('Multi-device not implemented yet for this case')
    else:
        # FIXME: if -u was passed in the command line then we are not saving the variables and thus
        # next line will generate an error in the script as the variable is 'undefined'
        logAction('flinging to end view with id=%s' % view.getId())
        print '%s%s.uiScrollable.flingToEnd()' % (indent, view.variableNameFromId())
    
def printOpenNotification():
    if options[CulebraOptions.MULTI_DEVICE]:
        warnings.warn('Multi-device not implemented yet for this case')
    else:
        logAction('opening Notification')
        print '%s%svc.uiDevice.openNotification()' % (indent, prefix)
    
def printOpenQuickSettings():
    if options[CulebraOptions.MULTI_DEVICE]:
        warnings.warn('Multi-device not implemented yet for this case')
    else:
        logAction('opening Quick Settings')
        print '%s%svc.uiDevice.openQuickSettings()' % (indent, prefix)
    
def printChangeLanguage(code):
    if options[CulebraOptions.MULTI_DEVICE]:
        warnings.warn('Multi-device not implemented yet for this case')
    else:
        logAction('Changing language to %s' % code)
        print '%s%svc.uiDevice.changeLanguage("%s")' % (indent, prefix, code)

def printTakeSnapshot(filename, _format, deviceart, dropshadow, screenglare):
    '''
    Prints the corresponding writeImageToFile() to take a snapshot
    '''
    
    if options[CulebraOptions.MULTI_DEVICE]:
        warnings.warn('Multi-device not implemented yet for this case')
    else:
        logAction(u'taking snapshot @ %s format=%s %s %s %s' % (filename, _format, deviceart, dropshadow, screenglare))
        print '%s%svc.writeImageToFile(\'%s\', \'%s\', \'%s\', %s, %s)' % (indent, prefix, filename, _format, deviceart, dropshadow, screenglare)
        
    
def traverseAndPrint(view):
    '''
    Traverses the View tree and prints the corresponding statement.

    @type view: L{View}
    @param view: the View
    '''

    if DEBUG:
        print >> sys.stderr, "traverseAndPrint(view=%s)" % view.getId()
    if options[CulebraOptions.VERBOSE_COMMENTS]:
        printVerboseComments(view)
    if options[CulebraOptions.FIND_VIEWS_BY_ID]:
        printFindViewById(view)
    if options[CulebraOptions.FIND_VIEWS_WITH_TEXT]:
        printFindViewWithText(view, options[CulebraOptions.USE_REGEXPS])
    if options[CulebraOptions.FIND_VIEWS_WITH_CONTENT_DESCRIPTION]:
        printFindViewWithContentDescription(view, options[CulebraOptions.USE_REGEXPS])
    if options[CulebraOptions.SAVE_VIEW_SCREENSHOTS]:
        _format = 'PNG'
        filename = options[CulebraOptions.SAVE_VIEW_SCREENSHOTS] + os.sep + view.variableNameFromId() + '.' + _format.lower()
        printSaveViewScreenshot(view, filename, _format)


def printStartActivity(component):
    '''
    Prints the corresponding startActivity().

    :param component: the component
    '''

    if options[CulebraOptions.MULTI_DEVICE]:
        warnings.warn('Multi-device not implemented yet for this case')
    else:
        logAction(u'starting activity=%s' % (component))
        print '%s%sdevice.startActivity(\'%s\')' % (indent, prefix, component)
    printSleep(3)


def printTouchViewUiAutomatorHelper(view, selector):
    '''
    Prints the corresponding touch
    '''
    if options[CulebraOptions.MULTI_DEVICE]:
        warnings.warn('Multi-device not implemented yet for this case')
    else:
        logAction(u'touching View by selector=%s' % (selector))
        print '%s%svc.touch(selector=\'%s\')' % (indent, prefix, selector)


def printLongTouchViewUiAutomatorHelper(view, selector):
    '''
    Prints the corresponding long touch
    '''
    if options[CulebraOptions.MULTI_DEVICE]:
        warnings.warn('Multi-device not implemented yet for this case')
    else:
        logAction(u'long-touching View by selector=%s' % (selector))
        print '%s%svc.longTouch(selector=\'%s\')' % (indent, prefix, selector)


def printSwipeUiAutomatorHelper(startX, startY, endX, endY, steps, unit, orientation):
    '''
    Prints a swipe
    '''

    if unit == Unit.PX:
        if options[CulebraOptions.MULTI_DEVICE]:
            warnings.warn('Multi-device not implemented yet for this case')
        else:
            print '%s%svc.swipe(startX=%d, startY=%d, endX=%d, endY=%d, steps=%d)' % (indent, prefix, startX, startY, endX, endY, steps)
    elif unit == Unit.DIP:
        if options[CulebraOptions.MULTI_DEVICE]:
            warnings.warn('Multi-device not implemented yet for this case')
        else:
            print '%s%svc.swipe(startX=%d, startY=%d, endX=%d, endY=%d, steps=%d)' % (indent, prefix, startX, startY, endX, endY, steps)
    else:
        raise RuntimeError('Invalid unit: %s' % unit)


def printPressBackUiAutomatorHelper():
    '''
    Prints the corresponding press
    '''
    if options[CulebraOptions.MULTI_DEVICE]:
        warnings.warn('Multi-device not implemented yet for this case')
    else:
        logAction(u'pressing BACK')
        print '%s%svc.pressBack()' % (indent, prefix)

def printPressHomeUiAutomatorHelper():
    '''
    Prints the corresponding press
    '''
    if options[CulebraOptions.MULTI_DEVICE]:
        warnings.warn('Multi-device not implemented yet for this case')
    else:
        logAction(u'pressing HOME')
        print '%s%svc.pressHome()' % (indent, prefix)

def printPressRecentAppsUiAutomatorHelper():
    '''
    Prints the corresponding press
    '''
    if options[CulebraOptions.MULTI_DEVICE]:
        warnings.warn('Multi-device not implemented yet for this case')
    else:
        logAction(u'pressing RECENT APPS')
        print '%s%svc.pressRecentApps()' % (indent, prefix)


def printOperation(view, op, *args):
    if len(args) == 0:
        # We use tuple values in the rest of this method, so if an empty tuple was passed
        # replace it by one containing None
        args = ( None, None )
    elif len(args) < 2:
        # We use tuple values in the rest of this method, so if an empty tuple was passed
        # replace it by one containing None
        args = ( args[0], None )
    if DEBUG:
        print >> sys.stderr, "printOperation(",
        print >> sys.stderr, view.__str__(),
        print >> sys.stderr, ",", op, ",",
        for a in args:
            if isinstance(a, unicode):
                print >> sys.stderr, a.encode(encoding='ascii', errors='replace'), ", ", 
            else:
                print >> sys.stderr, a,
        print >> sys.stderr, ")"
    if op == Operation.SLEEP:
        printSleep(secs=args[0])
        return
    elif op == Operation.PRESS:
        printPress(keycode=args[0])
        return
    elif op == Operation.PRESS_BACK:
        printPress('BACK')
        return
    elif op == Operation.PRESS_BACK_UI_AUTOMATOR_HELPER:
        printPressBackUiAutomatorHelper()
        return
    elif op == Operation.PRESS_HOME:
        printPress('HOME')
        return
    elif op == Operation.PRESS_HOME_UI_AUTOMATOR_HELPER:
        printPressHomeUiAutomatorHelper()
        return
    elif op == Operation.PRESS_RECENT_APPS:
        printPress('RECENT_APPS')
        return
    elif op == Operation.PRESS_RECENT_APPS_UI_AUTOMATOR_HELPER:
        printPressRecentAppsUiAutomatorHelper()
        return
    elif op == Operation.DUMP:
        printDump(window=args[0], dump=args[1])
        return
    elif op == Operation.DRAG:
        printDrag(start=args[0], end=args[1], duration=args[2], steps=args[3], unit=args[4], orientation=args[5])
        return
    elif op == Operation.TOUCH_POINT:
        printTouch(x=args[0], y=args[1], unit=args[2], orientation=args[3])
        return
    elif op == Operation.TOUCH_VIEW_UI_AUTOMATOR_HELPER:
        printTouchViewUiAutomatorHelper(view=view, selector=args[0])
        return
    elif op == Operation.LONG_TOUCH_POINT:
        printLongTouch(x=args[0], y=args[1], duration=args[2], unit=args[3], orientation=args[4])
        return
    elif op == Operation.LONG_TOUCH_VIEW_UI_AUTOMATOR_HELPER:
        printLongTouchViewUiAutomatorHelper(view=view, selector=args[0])
        return
    elif op == Operation.TRAVERSE:
        printTraverse()
        return
    elif op == Operation.SNAPSHOT:
        printTakeSnapshot(filename=args[0], _format=args[1], deviceart=args[2], dropshadow=args[3], screenglare=args[4])
        return
    elif op == Operation.SWIPE_UI_AUTOMATOR_HELPER:
        printSwipeUiAutomatorHelper(startX=args[0], startY=args[1], endX=args[2], endY=args[3], steps=args[4], unit=args[5], orientation=args[6])
        return
    elif op == Operation.VIEW_SNAPSHOT:
        printSaveViewScreenshot(view, filename=args[0], _format=args[1])
        return
# FIXME: I moved this to printFindViewWithContentDescription(..,op.,,) to solve the problem of variable not defined when
# the script is invoked with -u
#    elif op == Operation.FLING_BACKWARD:
#        printFlingBackward(view)
#        return
#    elif op == Operation.FLING_FORWARD:
#        printFlingForward(view)
#        return
#    elif op == Operation.FLING_TO_BEGINNING:
#        printFlingToBeginning(view)
#        return
#    elif op == Operation.FLING_TO_END:
#        printFlingToEnd(view)
#        return
    elif op == Operation.OPEN_NOTIFICATION:
        printOpenNotification()
        return
    elif op == Operation.OPEN_QUICK_SETTINGS:
        printOpenQuickSettings()
        return
    elif op == Operation.CHANGE_LANGUAGE:
        printChangeLanguage(code=args[0])
        return
    elif op == Operation.START_ACTIVITY:
        printStartActivity(component=args[0])
        return
    elif op == Operation.WAKE:
        printWake()
        return
    
    if view is None:
        warnings.warn('view is None. Perhaps you forgot to add some "op" in the previous if.')
        
    bd = Descriptor.findBestDescriptor(view)
    if bd == Descriptor.CONTENT_DESCRIPTION:
        printFindViewWithContentDescription(view, options[CulebraOptions.USE_REGEXPS], op, args[0])
    elif bd == Descriptor.TEXT:
        printFindViewWithText(view, options[CulebraOptions.USE_REGEXPS], op, args[0])
    else:
        printFindViewById(view, op, args[0])
        
def str2bool(v):
    if len(v) < 1 or len(v) > 5:
        # len('false')=5
        warnings.warn("str2bool: strange value for conversion '%s' will be considered 'false'" % v)
    return v.lower() in ("yes", "true", "t", "1", "on")

def value2dictionaryKey(v):
    v = v.lower()
    k = ['id', 'text', 'content-description']
    sk = ['i', 't', 'd']
    if v in k:
        return v
    if v in sk:
        return k[sk.index(v)]
    error("Invalid dictionary key: %s" % v)
    usage()

def getShebangJar():
    if options[CulebraOptions.USE_JAR]:
        import java
        osName = java.lang.System.getProperty('os.name')
        if osName == 'Linux':
            return SHEBANG[SB_JAR_LINUX]
        else:
            return SHEBANG[SB_JAR]
    else:
        return SHEBANG[SB_NO_JAR]

def getWindowOption():
    return options[CulebraOptions.WINDOW] if isinstance(options[CulebraOptions.WINDOW], str) and options[CulebraOptions.WINDOW][0] in '-0123456789' else "'%s'" % options[CulebraOptions.WINDOW]

def printScriptHeader():
    print '''%s
# -*- coding: utf-8 -*-
\'\'\'
Copyright (C) 2013-2016  Diego Torres Milano
Created on %s by Culebra v%s
                      __    __    __    __
                     /  \  /  \  /  \  /  \ 
____________________/  __\/  __\/  __\/  __\_____________________________
___________________/  /__/  /__/  /__/  /________________________________
                   | / \   / \   / \   / \   \___
                   |/   \_/   \_/   \_/   \    o \ 
                                           \_____/--<
@author: Diego Torres Milano
@author: Jennifer E. Swofford (ascii art snake)
\'\'\'


import re
import sys
import os
''' % (getShebangJar(), date.today(), __version__)

def printUnittestImport():
    print '''
import unittest
'''

def printAppendToSysPath():
    print '''
try:
    sys.path.append(os.path.join(os.environ['ANDROID_VIEW_CLIENT_HOME'], 'src'))
except:
    pass
'''

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

def printLogAction(action, priority='D'):
    # FIXME: This works only for CulebraTestCases
    # This relies on shortcut variables already set (i.e. _v)
    if options[CulebraOptions.MULTI_DEVICE]:
        print u'%s[_d.Log.%s(TAG, "%s", _v) for _d in %sallDevices()]' % (indent, priority.lower(), action, prefix)
    else:
        print '%s%sdevice.Log.%s(TAG, "%s",  _v)' % (indent, prefix, priority.lower(), action)
    
def logAction(action):
    if options[CulebraOptions.LOG_ACTIONS]:
        printLogAction(action)
    
def runCulebron():
    Culebron.checkSupportedSdkVersion(device.getSdkVersion())
    Culebron.checkDependencies()
    culebron = Culebron(vc, device, serialno, printOperation, options[CulebraOptions.SCALE], options[CulebraOptions.CONCERTINA])
    if options[CulebraOptions.DEVICE_ART]:
        culebron.deviceArt = options[CulebraOptions.DEVICE_ART]
        culebron.dropShadow = options[CulebraOptions.DROP_SHADOW]
        culebron.screenGlare = options[CulebraOptions.SCREEN_GLARE]
    culebron.takeScreenshotAndShowItOnWindow()
    culebron.mainloop()
    
def printShortcutVariables():
    if options[CulebraOptions.UNIT_TEST_CLASS] or options[CulebraOptions.UNIT_TEST_METHOD]:
        print '''\
        _s = CulebraTests.sleep
        _v = CulebraTests.verbose
'''
    else:
        print '''\
_s = 5
_v = '--verbose' in sys.argv
'''
    
################
# __main__
################
progname = os.path.basename(sys.argv[0])
try:
    optlist, args = getopt.getopt(sys.argv[1:], CulebraOptions.SHORT_OPTS, CulebraOptions.LONG_OPTS)
    sys.argv[1:] = args
except getopt.GetoptError, e:
    error(str(e))
    usage()

kwargs1 = {CulebraOptions.VERBOSE: False, 'ignoresecuredevice': False, 'ignoreversioncheck': False}
serialno = None
kwargs2 = {ViewClientOptions.FORCE_VIEW_SERVER_USE: False, ViewClientOptions.START_VIEW_SERVER: True,
           ViewClientOptions.AUTO_DUMP: False, ViewClientOptions.IGNORE_UIAUTOMATOR_KILLED: True,
           ViewClientOptions.COMPRESSED_DUMP: True,
           ViewClientOptions.USE_UIAUTOMATOR_HELPER: False,
           }
options = {CulebraOptions.FIND_VIEWS_BY_ID: True, CulebraOptions.FIND_VIEWS_WITH_TEXT: True,
           CulebraOptions.FIND_VIEWS_WITH_CONTENT_DESCRIPTION: True,
           CulebraOptions.USE_REGEXPS: False, CulebraOptions.VERBOSE_COMMENTS: False,
           CulebraOptions.UNIT_TEST_CLASS: False, CulebraOptions.UNIT_TEST_METHOD: None, CulebraOptions.USE_JAR: False,
           CulebraOptions.USE_DICTIONARY: False, CulebraOptions.DICTIONARY_KEYS_FROM: 'id',
           CulebraOptions.AUTO_REGEXPS: None, CulebraOptions.START_ACTIVITY: None, CulebraOptions.OUTPUT: None,
           CulebraOptions.INTERACTIVE: False,
           CulebraOptions.WINDOW: -1, CulebraOptions.PREPEND_TO_SYS_PATH: False,
           CulebraOptions.SAVE_SCREENSHOT: None, CulebraOptions.SAVE_VIEW_SCREENSHOTS: None,
           CulebraOptions.GUI: False,
           CulebraOptions.DO_NOT_VERIFY_SCREEN_DUMP: False,
           CulebraOptions.SCALE: 1,
           CulebraOptions.ORIENTATION_LOCKED: None,
           CulebraOptions.MULTI_DEVICE: False,
           CulebraOptions.LOG_ACTIONS: False,
           CulebraOptions.DEVICE_ART: None,
           CulebraOptions.DROP_SHADOW: False,
           CulebraOptions.SCREEN_GLARE: False,
           CulebraOptions.NULL_BACK_END: False,
           CulebraOptions.CONCERTINA: False,
           CulebraOptions.INSTALL_APK: None,
           }
transform = traverseAndPrint
for o, a in optlist:
    o = o.strip('-')
    if o in ['H', CulebraOptions.HELP]:
        help()
    elif o in ['V', CulebraOptions.VERBOSE]:
        kwargs1[CulebraOptions.VERBOSE] = True
    elif o in ['v', CulebraOptions.VERSION]:
        version()
    elif o in ['I', CulebraOptions.IGNORE_SECURE_DEVICE]:
        kwargs1['ignoresecuredevice'] = True
    elif o in ['E', CulebraOptions.IGNORE_VERSION_CHECK]:
        kwargs1['ignoreversioncheck'] = True
    elif o in ['F', CulebraOptions.FORCE_VIEW_SERVER_USE]:
        kwargs2[ViewClientOptions.FORCE_VIEW_SERVER_USE] = True
    elif o in ['S', CulebraOptions.DO_NOT_START_VIEW_SERVER]:
        kwargs2[ViewClientOptions.START_VIEW_SERVER] = False
    elif o in ['k', CulebraOptions.DO_NOT_IGNORE_UIAUTOMATOR_KILLED]:
        kwargs2[ViewClientOptions.IGNORE_UIAUTOMATOR_KILLED] = False
    elif o in ['w', CulebraOptions.WINDOW]:
         options[CulebraOptions.WINDOW] = a
    elif o in ['i', CulebraOptions.FIND_VIEWS_BY_ID]:
        options[CulebraOptions.FIND_VIEWS_BY_ID] = str2bool(a)
    elif o in ['t', CulebraOptions.FIND_VIEWS_WITH_TEXT]:
        options[CulebraOptions.FIND_VIEWS_WITH_TEXT] = str2bool(a)
    elif o in ['d', CulebraOptions.FIND_VIEWS_WITH_CONTENT_DESCRIPTION]:
        options[CulebraOptions.FIND_VIEWS_WITH_CONTENT_DESCRIPTION] = str2bool(a)
    elif o in ['r', CulebraOptions.USE_REGEXPS]:
        options[CulebraOptions.USE_REGEXPS] = True
    elif o in ['C', CulebraOptions.VERBOSE_COMMENTS]:
        options[CulebraOptions.VERBOSE_COMMENTS] = True
    elif o in ['U', CulebraOptions.UNIT_TEST_CLASS]:
        options[CulebraOptions.UNIT_TEST_CLASS] = True
    elif o in ['M', CulebraOptions.UNIT_TEST_METHOD]:
        if not a.startswith('test'):
            warnings.warn('Method name should start with "test"')
        options[CulebraOptions.UNIT_TEST_METHOD] = a
    elif o in ['j', CulebraOptions.USE_JAR]:
        options[CulebraOptions.USE_JAR] = str2bool(a)
    elif o in ['D', CulebraOptions.USE_DICTIONARY]:
        options[CulebraOptions.USE_DICTIONARY] = str2bool(a)
    elif o in ['K', CulebraOptions.DICTIONARY_KEYS_FROM]:
        options[CulebraOptions.DICTIONARY_KEYS_FROM] = value2dictionaryKey(a)
    elif o in ['R', CulebraOptions.AUTO_REGEXPS]:
        options[CulebraOptions.AUTO_REGEXPS] = a.split(',')
        for r in options[CulebraOptions.AUTO_REGEXPS]:
            if r == 'help':
                autoRegexpsHelp()
            if r == 'all':
                options[CulebraOptions.AUTO_REGEXPS] = CulebraOptions.AUTO_REGEXPS_RES.keys()
                break
            if r not in CulebraOptions.AUTO_REGEXPS_RES:
                error("invalid auto regexp: %s\n" % (r))
                usage()
        # CulebraOptions.AUTO_REGEPXS implies CulebraOptions.USE_REGEXPS
        options[CulebraOptions.USE_REGEXPS] = True
    elif o in ['a', CulebraOptions.START_ACTIVITY]:
        options[CulebraOptions.START_ACTIVITY] = a
    elif o in ['o', CulebraOptions.OUTPUT]:
        options[CulebraOptions.OUTPUT] = a
    elif o in ['p', CulebraOptions.PREPEND_TO_SYS_PATH]:
        options[CulebraOptions.PREPEND_TO_SYS_PATH] = True
    elif o in ['f', CulebraOptions.SAVE_SCREENSHOT]:
        options[CulebraOptions.SAVE_SCREENSHOT] = a
    elif o in ['W', CulebraOptions.SAVE_VIEW_SCREENSHOTS]:
        options[CulebraOptions.SAVE_VIEW_SCREENSHOTS] = a
    elif o in ['G', CulebraOptions.GUI]:
        options[CulebraOptions.GUI] = True
    elif o in ['u', CulebraOptions.DO_NOT_VERIFY_SCREEN_DUMP]:
        options[CulebraOptions.DO_NOT_VERIFY_SCREEN_DUMP] = True
    elif o in ['P', CulebraOptions.SCALE]:
        options[CulebraOptions.SCALE] = float(a)
    elif o in ['O', CulebraOptions.ORIENTATION_LOCKED]:
        options[CulebraOptions.ORIENTATION_LOCKED] = 'PENDING'
    elif o in ['s', CulebraOptions.SERIALNO]:
        __devices = a.split()
        if len(__devices) > 1:
            warnings.warn('List of devices not supported yet. Using first device instead.')
        serialno = __devices[0]
    elif o in ['m', CulebraOptions.MULTI_DEVICE]:
        options[CulebraOptions.MULTI_DEVICE] = True
    elif o in ['L', CulebraOptions.LOG_ACTIONS]:
        options[CulebraOptions.LOG_ACTIONS] = True
    elif o in ['A', CulebraOptions.DEVICE_ART]:
        options[CulebraOptions.DEVICE_ART] = a
    elif o in ['Z', CulebraOptions.DROP_SHADOW]:
        options[CulebraOptions.DROP_SHADOW] = True
    elif o in ['B', CulebraOptions.SCREEN_GLARE]:
        options[CulebraOptions.SCREEN_GLARE] = True
    elif o in ['0', CulebraOptions.NULL_BACK_END]:
        options[CulebraOptions.NULL_BACK_END] = True
    elif o in ['h', CulebraOptions.USE_UIAUTOMATOR_HELPER]:
        kwargs2[ViewClientOptions.USE_UIAUTOMATOR_HELPER] = True
    elif o in ['c', CulebraOptions.CONCERTINA]:
        options[CulebraOptions.CONCERTINA] = True
    elif o in ['1', CulebraOptions.INSTALL_APK]:
        options[CulebraOptions.INSTALL_APK] = a

if not (options[CulebraOptions.FIND_VIEWS_BY_ID] or options[CulebraOptions.FIND_VIEWS_WITH_TEXT] or options[CulebraOptions.FIND_VIEWS_WITH_CONTENT_DESCRIPTION]):
    if not options[CulebraOptions.VERBOSE_COMMENTS]:
        warnings.warn('All printing options disabled. Output will be empty.')
    else:
        warnings.warn('Only verbose comments will be printed')

if kwargs2[ViewClientOptions.FORCE_VIEW_SERVER_USE] and options[CulebraOptions.NULL_BACK_END]:
    warnings.warn(ViewClientOptions.FORCE_VIEW_SERVER_USE + " and " + CulebraOptions.NULL_BACK_END + " cannot be specified at the same time.")

if options[CulebraOptions.MULTI_DEVICE] and not options[CulebraOptions.UNIT_TEST_CLASS]:
    error("--" + CulebraOptions.MULTI_DEVICE + " only supported for unit tests (please specify --" + CulebraOptions.UNIT_TEST_CLASS + ")", fatal=True)

device, serialno = ViewClient.connectToDeviceOrExit(serialno=serialno, **kwargs1)
if options[CulebraOptions.ORIENTATION_LOCKED] == 'PENDING':
    options[CulebraOptions.ORIENTATION_LOCKED] = device.display['orientation']
if options[CulebraOptions.START_ACTIVITY]:
    device.startActivity(component=options[CulebraOptions.START_ACTIVITY])
if not options[CulebraOptions.NULL_BACK_END]:
    vc = ViewClient(device, serialno, **kwargs2)
else:
    vc = None
if options[CulebraOptions.OUTPUT]:
    sys.stdout = codecs.open(options[CulebraOptions.OUTPUT], mode='w', encoding='utf-8', errors='replace')
    import stat
    st = os.stat(options[CulebraOptions.OUTPUT])
    os.chmod(options[CulebraOptions.OUTPUT], st.st_mode | stat.S_IEXEC)

if options[CulebraOptions.UNIT_TEST_CLASS] or (not options[CulebraOptions.UNIT_TEST_METHOD]):
    printScriptHeader()

if options[CulebraOptions.UNIT_TEST_CLASS]:
    printUnittestImport()

if options[CulebraOptions.PREPEND_TO_SYS_PATH]:
    printPrependToSysPath()

if options[CulebraOptions.UNIT_TEST_CLASS] or (not options[CulebraOptions.UNIT_TEST_METHOD]):
    print '''\
from com.dtmilano.android.viewclient import ViewClient%s

TAG = '%s'
''' % (', CulebraTestCase' if options[CulebraOptions.UNIT_TEST_CLASS] else '', TAG)

if options[CulebraOptions.UNIT_TEST_CLASS]:
    print '''
class CulebraTests(CulebraTestCase):

    @classmethod
    def setUpClass(cls):
        cls.kwargs1 = %s
        cls.kwargs2 = %s
        cls.options = %s
        cls.sleep = 5

''' % (kwargs1, kwargs2, options),

    print '''\
    def setUp(self):
        super(CulebraTests, self).setUp()
'''

    print '''\
    def tearDown(self):
        super(CulebraTests, self).tearDown()
'''

    print '''\
    def preconditions(self):
        if not super(CulebraTests, self).preconditions():
            return False
''',

    if options[CulebraOptions.INSTALL_APK]:
        print '''\
        if self.vc.installPackage(\"%s\") != 0:
            return False
''' % (options[CulebraOptions.INSTALL_APK]),

    print '''\
        return True

    def %s(self):
        if not self.preconditions():
            self.fail('Preconditions failed')
''' % (options[CulebraOptions.UNIT_TEST_METHOD] if options[CulebraOptions.UNIT_TEST_METHOD] else 'testSomething')

    printShortcutVariables()
    
    if options[CulebraOptions.SAVE_SCREENSHOT]:
        print '''\
        self.vc.writeImageToFile('%s')
        ''' % options[CulebraOptions.SAVE_SCREENSHOT]
    
    if options[CulebraOptions.USE_DICTIONARY]:
        print '''\
        self.views = dict()'''

    if not options[CulebraOptions.GUI]:
        vc.dump(window=options[CulebraOptions.WINDOW])
    indent = ' ' * 8
    prefix = 'self.'
    
#     if not options[CulebraOptions.DO_NOT_VERIFY_SCREEN_DUMP]:
#         print '''\
#         self.vc.dump(%s)
#         ''' % getWindowOption()
#         vc.traverse(transform=transform)
#         print

    if options[CulebraOptions.GUI]:
        runCulebron()
    elif not options[CulebraOptions.DO_NOT_VERIFY_SCREEN_DUMP]:
        printDump(getWindowOption())
    else:
        print '''\
        ## your test code here ##
        '''

    print '''

if __name__ == '__main__':
    CulebraTests.main()
'''
else:
    # Not a unittest class, still could be a unittest method as we allow to generate methods separately from their classes
    if not options[CulebraOptions.UNIT_TEST_METHOD]:
        printShortcutVariables()
        print '''
kwargs1 = %s
device, serialno = ViewClient.connectToDeviceOrExit(**kwargs1)
''' % kwargs1,

    if options[CulebraOptions.START_ACTIVITY] and not options[CulebraOptions.UNIT_TEST_METHOD]:
        print '''\
device.startActivity(component='%s')''' % options[CulebraOptions.START_ACTIVITY]

    if not options[CulebraOptions.UNIT_TEST_METHOD]:
        print '''\
kwargs2 = %s
vc = ViewClient(device, serialno, **kwargs2)
#vc.dump(window=%s) # FIXME: seems not needed
''' % (kwargs2, getWindowOption())

        if options[CulebraOptions.USE_DICTIONARY]:
            print '''views = dict()'''

        if options[CulebraOptions.SAVE_SCREENSHOT]:
            print '''\
vc.writeImageToFile('%s')
''' % options[CulebraOptions.SAVE_SCREENSHOT]

    if vc:
        vc.dump(window=options[CulebraOptions.WINDOW])
    if options[CulebraOptions.UNIT_TEST_METHOD]:
        print '''
    def %s(self):
        \'\'\'
        Test method.
        \'\'\'

        if not self.preconditions():
            self.fail('Preconditions failed')
''' % (options[CulebraOptions.UNIT_TEST_METHOD])
        indent = ' ' * 8
        prefix = 'self.'
        printShortcutVariables()
    
    if options[CulebraOptions.GUI]:
        runCulebron()
    elif not options[CulebraOptions.DO_NOT_VERIFY_SCREEN_DUMP]:
        printDump(getWindowOption())

if kwargs2[ViewClientOptions.USE_UIAUTOMATOR_HELPER]:
    try:
        vc.uiAutomatorHelper.quit()
    except:
        pass

if options[CulebraOptions.INTERACTIVE]:
    import socket
    HOST = 'localhost'
    PORT = 8900
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((HOST, PORT))
    s.sendall("RECORD EVENTS START\n")
    fin = open("/dev/tty")
    while True:
        print >> sys.stderr, "Reading events..."
        data = s.recv(1024)
        code = ViewClient.excerpt(data)
        exec code
        resp = raw_input("Continue recording events? [Y/n]: ")
        if resp in ['N', 'n']:
            break
    s.sendall("RECORD EVENTS STOP\n")
    s.close()

