"""
profile - profile moin moin

Usage:

    python profile.py action [options]

Actions:

    -a --all            profile pages listed on SystemPagesInEnglishGroup
    -p --page pagename  profile pagename  
    
Options:

    -r --requests num   how many requests to run for each page
                        (default 500)
    
    -s --sleep seconds  how much time to sleep after each request
                        (default 0.1)

Notes:

    Run the script from the distribution directory, where MoinMoin
    package lives. You can can also set the system path.
"""

import sys
import os
import re
import gc
import time
from cStringIO import StringIO

# choose your paths:
#import sys
#sys.path[0:0]=['/var/www/virtualdomains/moin-main/lib/python',
#               '/var/www/virtualdomains/moin-main/wiki']

from MoinMoin.request import RequestCLI


def memory():
    """ Return memory usage of current process in KB """
    datafile = os.popen('ps -p %s -o rss' % os.getpid())
    line = datafile.readlines()[1] 
    datafile.close()
    return line.strip()  

_name_re = None
def englishSystemPages():
    """ Return a list of pages in the English system pages group """
    global _name_re
    if not _name_re:
        _name_re = re.compile(r'^ \*\s+(?:\[")?(?P<name>.+?)(?:"\])?$', re.MULTILINE)
    groupfile = file('wiki/data/text/SystemPagesInEnglishGroup')
    text = groupfile.read()
    groupfile.close()
    names = [match.group('name') for match in _name_re.finditer(text)]
    return names
    
def getPage(pagename, output):
    """ Get page into output """
    request = RequestCLI(pagename=pagename)
    request.redirect(output)
    request.run()
    del request
    
def do_profile(options):
    """ Test pages """
    max = options['requests']
    samples = max / 10
    sleep = options['sleep']   
    
    for pagename in options['pagenames']:
        print
        print pagename
        requests = 0
        while requests < max:
            # Run some requests
            for i in range(samples):
                output = StringIO()
                getPage(pagename='FrontPage', output=output)
                time.sleep(sleep)
                del output
                requests += 1
                if requests >= max: break
            # Sample
            print 'requests:%d  memory:%sKB  collect:%d  objects:%d  garbage:%d' % (
                requests, memory(), gc.collect(), len(gc.get_objects()), len(gc.garbage))

def do_error(message):
    print 'Error:', message
    print __doc__
    sys.exit(1)
    
def main():
    import getopt
    import warnings

    # Ignore import moin_config did not import warnings
    warnings.filterwarnings('ignore',
                            r'^import of config .+ default configuration used instead.')
    
    action = None
    options = {'requests': 500, 'sleep': 0.1}

    try:
        optlist, args = getopt.getopt(sys.argv[1:], 'ap:r:s:',
                                      ['all', 'page=', 'requests=', 'sleep='])           
        for opt, val in optlist:
            if '-a' in opt:
                options['pagenames'] = englishSystemPages()
            elif '-p' in opt:
                options['pagenames'] = [val]
            elif '-r' in opt:
                options['requests'] = int(val)
            elif '-s' in opt:
                options['sleep'] = float(val)

        if not options.has_key('pagenames'):
            do_error('Nothing to do')
        do_profile(options)
        
    except (getopt.GetoptError, ValueError), why:
        do_error(str(why))
    
    
if __name__ == '__main__':
    main()
    

