#!/usr/bin/env python

#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

from collections import namedtuple

import pytest

import merge_arrow_pr


FakeIssue = namedtuple('issue', ['fields'])
FakeFields = namedtuple('fields', ['status', 'summary', 'assignee',
                                   'components'])
FakeAssignee = namedtuple('assignee', ['displayName'])
FakeStatus = namedtuple('status', ['name'])
FakeComponent = namedtuple('component', ['name'])
FakeProjectVersion = namedtuple('version', ['name', 'raw'])

RAW_VERSION_JSON = [
    {'version': 'JS-0.4.0', 'released': False},
    {'version': '0.11.0', 'released': False},
    {'version': '0.12.0', 'released': False},
    {'version': '0.10.0', 'released': True},
    {'version': '0.9.0', 'released': True}
]


SOURCE_VERSIONS = [FakeProjectVersion(raw['version'], raw)
                   for raw in RAW_VERSION_JSON]

TRANSITIONS = [{'name': 'Resolve Issue', 'id': 1}]

jira_id = 'ARROW-1234'
status = FakeStatus('In Progress')
fields = FakeFields(status, 'issue summary', FakeAssignee('groundhog'),
                    [FakeComponent('C++'), FakeComponent('Format')])
FAKE_ISSUE_1 = FakeIssue(fields)


class FakeJIRA:

    def __init__(self, issue=None, project_versions=None, transitions=None):
        self._issue = issue
        self._project_versions = project_versions
        self._transitions = transitions

    def issue(self, jira_id):
        return self._issue

    def transitions(self, jira_id):
        return self._transitions

    def transition_issue(self, jira_id, transition_id, comment=None,
                         fixVersions=None):
        self.captured_transition = {
            'jira_id': jira_id,
            'transition_id': transition_id,
            'comment': comment,
            'fixVersions': fixVersions
        }

    def get_candidate_fix_versions(self):
        return SOURCE_VERSIONS, ['0.12.0']

    def project_versions(self, project):
        return self._project_versions


class FakeCLI:

    def __init__(self, responses=()):
        self.responses = responses
        self.position = 0

    def prompt(self, prompt):
        response = self.responses[self.position]
        self.position += 1
        return response

    def fail(self, msg):
        raise Exception(msg)


def test_jira_fix_versions():
    jira = FakeJIRA(project_versions=SOURCE_VERSIONS,
                    transitions=TRANSITIONS)

    issue = merge_arrow_pr.JiraIssue(jira, 'ARROW-1234', 'ARROW', FakeCLI())
    all_versions, default_versions = issue.get_candidate_fix_versions()
    assert all_versions == SOURCE_VERSIONS
    assert default_versions == ['0.11.0']


def test_jira_no_suggest_patch_release():
    versions_json = [
        {'version': '0.11.1', 'released': False},
        {'version': '0.12.0', 'released': False},
    ]

    versions = [FakeProjectVersion(raw['version'], raw)
                for raw in versions_json]

    jira = FakeJIRA(project_versions=versions, transitions=TRANSITIONS)
    issue = merge_arrow_pr.JiraIssue(jira, 'ARROW-1234', 'ARROW', FakeCLI())
    all_versions, default_versions = issue.get_candidate_fix_versions()
    assert all_versions == versions
    assert default_versions == ['0.12.0']


def test_jira_invalid_issue():
    class Mock:

        def issue(self, jira_id):
            raise Exception("not found")

    with pytest.raises(Exception):
        merge_arrow_pr.JiraIssue(Mock(), 'ARROW-1234', 'ARROW', FakeCLI())


def test_jira_resolve():
    jira = FakeJIRA(issue=FAKE_ISSUE_1,
                    project_versions=SOURCE_VERSIONS,
                    transitions=TRANSITIONS)

    my_comment = 'my comment'
    fix_versions = [SOURCE_VERSIONS[1].raw]

    issue = merge_arrow_pr.JiraIssue(jira, 'ARROW-1234', 'ARROW', FakeCLI())
    issue.resolve(fix_versions, my_comment)

    assert jira.captured_transition == {
        'jira_id': 'ARROW-1234',
        'transition_id': 1,
        'comment': my_comment,
        'fixVersions': fix_versions
    }


def test_jira_resolve_non_mainline():
    jira = FakeJIRA(issue=FAKE_ISSUE_1,
                    project_versions=SOURCE_VERSIONS,
                    transitions=TRANSITIONS)

    my_comment = 'my comment'
    fix_versions = [SOURCE_VERSIONS[0].raw]

    issue = merge_arrow_pr.JiraIssue(jira, 'ARROW-1234', 'ARROW', FakeCLI())
    issue.resolve(fix_versions, my_comment)

    assert jira.captured_transition == {
        'jira_id': 'ARROW-1234',
        'transition_id': 1,
        'comment': my_comment,
        'fixVersions': fix_versions
    }


def test_jira_resolve_released_fix_version():
    # ARROW-5083
    jira = FakeJIRA(issue=FAKE_ISSUE_1,
                    project_versions=SOURCE_VERSIONS,
                    transitions=TRANSITIONS)

    cmd = FakeCLI(responses=['0.9.0'])
    fix_versions_json = merge_arrow_pr.prompt_for_fix_version(cmd, jira)
    assert fix_versions_json == [RAW_VERSION_JSON[-1]]


def test_multiple_authors_bad_input():
    a0 = 'Jimbob Crawfish <jimbob.crawfish@gmail.com>'
    a1 = 'Jarvis McCratchett <jarvis.mccratchett@hotmail.com>'
    a2 = 'Hank Miller <hank.miller@protonmail.com>'
    distinct_authors = [a0, a1]

    cmd = FakeCLI(responses=[''])
    primary_author, new_distinct_authors = merge_arrow_pr.get_primary_author(
        cmd, distinct_authors)
    assert primary_author == a0
    assert new_distinct_authors == [a0, a1]

    cmd = FakeCLI(responses=['oops', a1])
    primary_author, new_distinct_authors = merge_arrow_pr.get_primary_author(
        cmd, distinct_authors)
    assert primary_author == a1
    assert new_distinct_authors == [a1, a0]

    cmd = FakeCLI(responses=[a2])
    primary_author, new_distinct_authors = merge_arrow_pr.get_primary_author(
        cmd, distinct_authors)
    assert primary_author == a2
    assert new_distinct_authors == [a2, a0, a1]


def test_jira_already_resolved():
    status = FakeStatus('Resolved')
    fields = FakeFields(status, 'issue summary', FakeAssignee('groundhog'),
                        [FakeComponent('Java')])
    issue = FakeIssue(fields)

    jira = FakeJIRA(issue=issue,
                    project_versions=SOURCE_VERSIONS,
                    transitions=TRANSITIONS)

    fix_versions = [SOURCE_VERSIONS[0].raw]
    issue = merge_arrow_pr.JiraIssue(jira, 'ARROW-1234', 'ARROW', FakeCLI())

    with pytest.raises(Exception,
                       match="ARROW-1234 already has status 'Resolved'"):
        issue.resolve(fix_versions, "")


def test_jira_output_no_components():
    # ARROW-5472
    status = 'Interesting work'
    components = []
    output = merge_arrow_pr.format_jira_output(
        'ARROW-1234', 'Resolved', status, FakeAssignee('Foo Bar'),
        components)

    assert output == """=== JIRA ARROW-1234 ===
Summary\t\tInteresting work
Assignee\tFoo Bar
Components\tNO COMPONENTS!!!
Status\t\tResolved
URL\t\thttps://issues.apache.org/jira/browse/ARROW-1234"""

    output = merge_arrow_pr.format_jira_output(
        'ARROW-1234', 'Resolved', status, FakeAssignee('Foo Bar'),
        [FakeComponent('C++'), FakeComponent('Python')])

    assert output == """=== JIRA ARROW-1234 ===
Summary\t\tInteresting work
Assignee\tFoo Bar
Components\tC++, Python
Status\t\tResolved
URL\t\thttps://issues.apache.org/jira/browse/ARROW-1234"""
