#!/usr/bin/env python
import os
import sys
import time
import json
import base64
import httplib
import util

def http_client(method, resource, args):
    req = json.dumps(args)

    conn.request(method, resource, req)

    response = conn.getresponse()
    res      = response.read()

    logger.log('API', ('method({0}) resource({1}) status({2}) reason({3}) ' +
                'request({4}) response({5})').format(
        method, resource, response.status, response.reason,
        logger.blob(req), logger.blob(res)))

    try:
        body = json.loads(res)
    except ValueError:
        body = None

    return response.status, response.reason, body

app    = json.load(open('{0}.key'.format(os.getuid())))
conn   = httplib.HTTPConnection(app['api_host'] + ':' + str(app['api_port']))
logger = util.Logger('worker')

sys.path.append(os.path.dirname(app['path']))
import worker

while True:
    status, reason, msg = http_client('POST', 'lockmessage', app)
    if (200 != status) or ('NOT_FOUND' == msg):
        break

    event = dict(code=msg['code'])
    if 'data' in msg:
        event['data'] = base64.b64decode(msg['data'])

    result = worker.worker(base64.b64decode(msg['input']),
                           base64.b64decode(msg['continuation']),
                           event,
                           util.Logger(msg['workername'], msg['session']))

    if result is None:
        result = dict(status='worker crashed')

    if 'status' in result:
        result['status'] = base64.b64encode(result['status'])

    if 'state' in result:
        result['continuation'] = base64.b64encode(result['state'])

    for m in result.get('message', []):
        if 'data' in m:
            m['data'] = base64.b64encode(m['data'])

    result['msgid']      = msg['msgid']
    result['workername'] = msg['workername']

    http_client('POST', 'commit', dict(commit=result,
                                       appname=app['appname'],
                                       authkey=app['authkey']))
