
from urllib import urlencode
import urllib2
import re
import threading
import time
import functools

context_path = "jboss-numberguess"

def get_re(r, ret):
    m = re.search(r, ret)
    if m is not None:
        return m.group(1)

    return None

get_view_state = lambda ret: get_re(r'javax.faces.ViewState:?0?" value="([^"]+)"', ret)
get_action_url = lambda ret: get_re(r'action="([^"]+)"', ret)

def initial_request():
    r_setcookie = r'Set-Cookie: JSESSIONID=([^;]+);'

    f = urllib2.urlopen("http://127.0.0.1:8080/%s/home.jsf" % context_path)
    ret = f.read()

    cookie = None
    for header in f.info().headers:
        m = re.search(r_setcookie, header)
        if m is not None:
            cookie = m.group(1)

    return (cookie, ret)

class MyHTTPRedirectHandler(urllib2.HTTPRedirectHandler):
    pass
#    def http_error_302(self, req, fp, code, msg, headers):
        # do another request first
        #TestThread("1", initial_request).start()
        #print ("XXX background request: " + cookie)
#        return urllib2.HTTPRedirectHandler.http_error_302(self, req, fp, code, msg, headers)

def _post_request(button_id, button_value, sessionid, viewState, action):
    cookieprocessor = urllib2.HTTPCookieProcessor()
    opener = urllib2.build_opener(MyHTTPRedirectHandler, cookieprocessor)
#     urllib2.install_opener(opener)
    opener.addheaders.append(('Cookie', 'JSESSIONID=' + sessionid))

    data = []
    data.append( ("javax.faces.ViewState", viewState) )
    data.append( ("form", "form") )
    data.append( (button_id, button_value))

    f = opener.open("http://127.0.0.1:8080" + action, urlencode(data))
    ret = f.read()
    return ret

begin_post_request = lambda sessionid, view_state, action: _post_request("form:begin", "Begin", sessionid, view_state, action)
end_post_request = lambda sessionid, view_state, action: _post_request("form:end", "End", sessionid, view_state, action)
invalidate_post_request = lambda sessionid, view_state, action: _post_request("form:invalidate", "Invalidate", sessionid, view_state, action)

class TestThread(threading.Thread):
    def __init__ (self, threadid, f):
        self.threadid = threadid
        self.f = f
        threading.Thread.__init__ (self)

    def run(self):
        ret = self.f()
        print (str(self.threadid))

#cookie, ret = initial_request()
#view_state = get_view_state(ret)
#action = get_action_url(ret)


#ret = begin_post_request(cookie, view_state, action)
#view_state = get_view_state(ret)
#action = get_action_url(ret)


count = 0

while True:
    cookie, ret = initial_request()
    view_state = get_view_state(ret)
    action = get_action_url(ret)

    print "view_state: " + `view_state`

    ret = begin_post_request(cookie, view_state, action)
    view_state = get_view_state(ret)
    action = get_action_url(ret)

    print action

    #end_post_request(cookie, view_state, action)
    #end_post_request(cookie, view_state, action)

    TestThread("end", functools.partial(end_post_request, cookie, view_state, action)).start()
    TestThread("end2", functools.partial(end_post_request, cookie, view_state, action)).start()

#    TestThread("invalidate", functools.partial(invalidate_post_request, cookie, view_state, action)).start()

    break

    count += 1

    if count > 5:
        break

#print `cookie`
