import urllib
import urlparse

from django.conf import settings
from django.core.urlresolvers import reverse
from django.http import HttpResponse
from django.utils.translation import ugettext_lazy as _
from sentry.models import GroupMeta
from sentry.plugins.base import Response
from sentry.plugins.bases.issue import IssuePlugin
from sentry.utils import json

from sentry_jira import VERSION as PLUGINVERSION
from sentry_jira.forms import JIRAOptionsForm, JIRAIssueForm
from sentry_jira.jira import JIRAClient


class JIRAPlugin(IssuePlugin):
    author = "Adam Thurlow"
    author_url = "https://github.com/thurloat/sentry-jira"
    version = PLUGINVERSION

    slug = "jira"
    title = _("JIRA")
    conf_title = title
    conf_key = slug
    project_conf_form = JIRAOptionsForm
    project_conf_template = "sentry_jira/project_conf_form.html"
    new_issue_form = JIRAIssueForm
    create_issue_template = 'sentry_jira/create_jira_issue.html'

    # Adding resource links for forward compatibility, still need to integrate
    # into existing `project_conf.html` template.
    resource_links = [
        ("Documentation", "http://sentry-jira.readthedocs.org/en/latest/"),
        ("README", "https://raw.github.com/thurloat/sentry-jira/master/README.rst"),
        ("Bug Tracker", "https://github.com/thurloat/sentry-jira/issues"),
        ("Source", "http://github.com/thurloat/sentry-jira"),
    ]

    def is_configured(self, request, project, **kwargs):
        if not self.get_option('default_project', project):
            return False
        return True

    def get_jira_client(self, project):
        instance = self.get_option('instance_url', project)
        username = self.get_option('username', project)
        pw = self.get_option('password', project)
        return JIRAClient(instance, username, pw)

    def get_initial_form_data(self, request, group, event, **kwargs):
        initial = {
            'summary': self._get_group_title(request, group, event),
            'description': self._get_group_description(request, group, event),
            'project_key': self.get_option('default_project', group.project),
            'issuetype': request.POST.get('issuetype'),
            'jira_client': self.get_jira_client(group.project)
        }

        return initial

    def get_new_issue_title(self):
        return "Create JIRA Issue"

    def create_issue(self, request, group, form_data, **kwargs):
        """
        Form validation errors recognized server-side raise ValidationErrors,
        but when validation errors occur in JIRA they are simply attached to
        the form.
        """
        jira_client = self.get_jira_client(group.project)
        issue_response = jira_client.create_issue(form_data)

        if issue_response.status_code in [200, 201]: # weirdly inconsistent.
            return issue_response.json.get("key"), None
        else:
            # return some sort of error.
            errdict = {"__all__": None}
            if issue_response.status_code == 500:
                errdict["__all__"] = "JIRA Internal Server Error."
            elif issue_response.status_code == 400:
                for k in issue_response.json["errors"].keys():
                    errdict[k] = [issue_response.json["errors"][k],]
                errdict["__all__"] = issue_response.json["errorMessages"]
            else:
                errdict["__all__"] = "Something went wrong, Sounds like a configuration issue: code %s" % issue_response.status_code
            return None, errdict

    def get_issue_url(self, group, issue_id, **kwargs):
        instance = self.get_option('instance_url', group.project)
        return "%s/browse/%s" % (instance, issue_id)

    def view(self, request, group, **kwargs):
        """
        Overriding the super to alter the error checking functionality. Method
        source had to be copied in an altered, see huge comment below for changes.
        """
        has_auth_configured = self.has_auth_configured()
        if not (has_auth_configured and self.is_configured(project=group.project, request=request)):
            if self.auth_provider:
                providers = settings.AUTH_PROVIDERS if hasattr(
                    settings, 'AUTH_PROVIDERS') else settings.SENTRY_AUTH_PROVIDERS
                required_auth_settings = providers[self.auth_provider]
            else:
                required_auth_settings = None

            return self.render(self.not_configured_template, {
                'title': self.get_title(),
                'project': group.project,
                'has_auth_configured': has_auth_configured,
                'required_auth_settings': required_auth_settings,
                })

        if self.needs_auth(project=group.project, request=request):
            return self.render(self.needs_auth_template, {
                'title': self.get_title(),
                'project': group.project,