import json
import logging
import re
import StringIO
import sys
import time
import gzip

if 'code' in sys.modules:
    del sys.modules['code']
from code.justin.tv.dta.rockpaperscissors import environment
from code.justin.tv.dta.rockpaperscissors import event_bus


logger = logging.getLogger()
logger.setLevel(logging.INFO)
logging.getLogger('boto3').setLevel(logging.WARNING)
logging.getLogger('botocore').setLevel(logging.WARNING)


OK_RETURN = {
    'statusCode': '200',
    'headers': {},
    'body': 'OK'}


def lambda_handler(event, context):
    github_event_type = event['headers']['X-GitHub-Event']
    logger.info('Received %s webhook delivery ID: %s',
                github_event_type,
                event['headers'].get('X-GitHub-Delivery', 'unknown'))
    body = str(event['body'])
    timestamp = time.time()

    attributes = None
    if github_event_type == 'push':
        push_event = json.loads(body)
        attributes = {
          'github_repository': push_event['repository']['url'],
          'pusher': push_event['pusher']['name'],
          'branch': re.sub(r'^refs/heads/', '', push_event['ref']),
        }
        # TODO: also compress github push events
    else:
        body = compress(body, filename=github_event_type, mtime=timestamp)

    if github_event_type == 'pull_request':
        pull_request_event = json.loads(event['body'])
        pull_request_action = pull_request_event['action']

        # We only care about pull_requests whose action is one of these.
        if pull_request_action not in ["opened", "closed", "review_requested"]:
            return OK_RETURN

        # Type will be like GitHub-pull_request-opened
        github_event_type += '-' + pull_request_action
        attributes = {
          'head_repository': pull_request_event['pull_request']['head']['repo']['html_url'],
          'head_ref': pull_request_event['pull_request']['head']['ref'],
          'base_repository': pull_request_event['pull_request']['base']['repo']['html_url'],
          'base_ref': pull_request_event['pull_request']['base']['ref'],
          'user': pull_request_event['pull_request']['user']['login'],
        }
    if github_event_type == 'deployment_status':
        deployment_status_event = json.loads(event['body'])
        attributes = {
          'github_repository': deployment_status_event['repository']['html_url'],
          'deployment_state': deployment_status_event['deployment_status']['state'],
          'creator': deployment_status_event['deployment']['creator']['login'],
        }

    e = event_bus.Event('GitHub-%s' % github_event_type, body,
                        timestamp=timestamp,
                        attributes=attributes)

    env = environment.GetEnvironment(context)
    bus = env.EventBus()
    bus.PutEvent(e)

    return OK_RETURN


def compress(contents, filename=None, mtime=None):
    z = StringIO.StringIO()
    with gzip.GzipFile(filename=filename, mode='wb', fileobj=z, mtime=mtime) as fo:
        fo.write(contents)
    return z.getvalue()
