""" Code related to github webhooks and API calls. """

import copy
import os

import requests
from werkzeug.exceptions import BadRequest


IGNORED_USERS = os.environ.get('IGNORED_USERS', '').split(',')


def is_valid_pull_request(data):
    """ Verify that the request from github is a valid review request. """

    is_valid_request = _validate_pull_request(data)
    is_valid_action = data.get('action') == 'review_requested' or data.get('action') == 'assigned'

    return is_valid_request and is_valid_action


def _validate_pull_request(data):

    if 'action' not in data:
        raise BadRequest('no event supplied')

    if 'pull_request' not in data or 'html_url' not in data.get('pull_request'):
        raise BadRequest('payload.pull_request.html_url missing')

    if data.get('sender', {}).get('login') in IGNORED_USERS:
        return False

    return True


def get_recipient_github_username_by_action(data):
    """ Parse and return the recipient username by action type. """
    payload_parser = GithubWebhookPayloadParser(data)

    if data.get('action') == 'review_requested':
        username = payload_parser.get_request_reviewer_username()
    elif data.get('action') == 'assigned':
        username = payload_parser.get_assignee_username()
    else:
        raise BadRequest('Github username not found')

    return username


def lookup_github_full_name(gh_username):
    """ Retrieve a github user's full name by username. """
    url = 'https://api.github.com/users/{}'.format(gh_username)
    request = requests.get(url, auth=(os.environ.get('GITHUB_API_USER', ''), os.environ.get('GITHUB_API_TOKEN', '')))
    user = request.json()
    return user.get('name', '')


class GithubWebhookPayloadParser:
    """ A class to parse a github payload and return specific elements. """

    def __init__(self, data=None):
        if data is None:
            data = {}
        self._data = copy.deepcopy(data)

    def get_request_reviewer_username(self):
        """ Parse and retrieve the requested reviewer username. """
        return self._data.get('requested_reviewer', {}).get('login')

    def get_assignee_username(self):
        """ Parse and retrieve the assignee's username. """
        return self._data.get('assignee', {}).get('login')

    def get_pull_request_title(self):
        """ Parse and retrieve the pull request title. """
        return self._data.get('pull_request', {}).get('title')

    def get_pull_request_url(self):
        """ Parse and retrieve the pull request html url. """
        return self._data.get('pull_request', {}).get('html_url')

    def get_pull_request_repo(self):
        """ Parse and retrieve the pull request repository name. """
        return self._data.get('repository', {}).get('full_name')

    def get_pull_request_number(self):
        """ Parse and retrieve the pull request number. """
        return self._data.get('number')

    def get_pull_request_author(self):
        """ Parse and retrieve the pull request author. """
        return self._data.get('pull_request', {}).get('user', {}).get('login')

    def get_pull_request_author_image(self):
        """ Parse and retrieve the pull request author image. """
        return self._data.get('pull_request', {}).get('user', {}).get('avatar_url')

    def get_pull_request_description(self):
        """ Parse and retrieve the pull request repository description. """
        return self._data.get('pull_request', {}).get('body')
