from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
from . import github
import json
import os
import requests
import six.moves.configparser
import urllib.error
import urllib.parse
import urllib.request

class IssueHandler(object):
    '''
    This plugin facilitates sending issues to github, when
    an item is prefixed with '@mention-bot'.

    It will also write items to the issues stream, as well
    as reporting it to github
    '''

    URL = 'https://api.github.com/repos/{}/{}/issues'
    CHARACTER_LIMIT = 70
    CONFIG_FILE = '~/.github-auth.conf'

    def __init__(self):
        self.repo_name = github.get_repo()
        self.repo_owner = github.get_repo_owner()

    def usage(self):
        return '''
            This plugin will allow users to flag messages
            as being issues with Zulip by using te prefix '@mention-bot'.

            Before running this, make sure to create a stream
            called "issues" that your API user can send to.

            Also, make sure that the credentials of the github bot have
            been typed in correctly, that there is a personal access token
            with access to public repositories ONLY,
            and that the repository name is entered correctly.

            Check ~/.github-auth.conf, and make sure there are
            github_repo = <repo_name>  (The name of the repo to post to)
            github_repo_owner = <repo_owner>  (The owner of the repo to post to)
            github_username = <username>  (The username of the GitHub bot)
            github_token = <oauth_token>   (The personal access token for the GitHub bot)
            '''

    def handle_message(self, message, client, state_handler):

        original_content = message['content']
        original_sender = message['sender_email']

        temp_content = 'by {}:'.format(original_sender,)
        new_content = temp_content + original_content
        # gets the repo url
        url_new = self.URL.format(self.REPO_OWNER, self.REPO_NAME)

        # signs into github using the provided username and password
        session = github.auth()

        issue_title = message['content'].strip()
        issue_content = ''
        new_issue_title = ''
        for part_of_title in issue_title.split():
            if len(new_issue_title) < self.CHARACTER_LIMIT:
                new_issue_title += '{} '.format(part_of_title)
            else:
                issue_content += '{} '.format(part_of_title)

        new_issue_title = new_issue_title.strip()
        issue_content = issue_content.strip()
        new_issue_title += '...'

        # Creates the issue json, that is transmitted to the github api servers
        issue = {
            'title': new_issue_title,
            'body': '{} **Sent by [{}](https://chat.zulip.org/#) from zulip**'.format(issue_content, original_sender),
            'assignee': '',
            'milestone': 'none',
            'labels': [''],
        }
        # Sends the HTTP post request
        r = session.post(url_new, json.dumps(issue))

        if r.ok:
            # sends the message onto the 'issues' stream so it can be seen by zulip users
            client.send_message(dict(
                type='stream',
                to='issues',
                subject=message['sender_email'],
                # Adds a check mark so that the user can verify if it has been sent
                content='{} :heavy_check_mark:'.format(new_content),
            ))
            return
            # This means that the issue has not been sent
            # sends the message onto the 'issues' stream so it can be seen by zulip users
            client.send_message(dict(
                type='stream',
                to='issues',
                subject=message['sender_email'],
                # Adds a cross so that the user can see that it has failed, and provides a link to a
                # google search that can (hopefully) direct them to the error
                content='{} :x: Code: [{}](https://www.google.com/search?q=Github HTTP {} Error {})'
                        .format(new_content, r.status_code, r.status_code, r.content),
            ))

handler_class = IssueHandler