from itertools import chain, groupby

from ids.exceptions import BackendError

from ..base import OperationBase, lib


@lib.register
class LinkTripConfIssues(OperationBase):
    def match_preconditions(self):
        return (
            self.TC.is_trip_conf
            and
            self.TC.is_trip_toplevel_issue_created
            and
            self.TC.is_conf_toplevel_issue_created
            and
            self.TC.is_all_toplevel_issues_created
            and
            self.TC.is_all_personal_issues_created
            and
            not self.TC.is_all_issues_links_created
        )

    def run(self):
        issues_mapping = groupby(self.iter_initiators(), self.issues_getter)

        for link, initiators in (self.make_link(g) for g in issues_mapping):
            self.set_link(link, initiators)

    def issues_getter(self, initiator):
        return (self.get_interconf_issue_key(initiator),
                self.get_travel_issue_key(initiator))

    def iter_initiators(self):
        all_initiators = chain([self.trip.data], self.trip.data['employee_list'])
        return (
            i for i in all_initiators
            if not i.get('is_issue_link_created', False)
        )

    def get_interconf_issue_key(self, initiator):
        return initiator['conf_issue']['key']

    def get_travel_issue_key(self, initiator):
        return initiator['trip_issue']['key']

    def make_link(self, group):
        (interconf_issue_key, travel_issue_key), initiators = group

        issue = (
            self.operations_cache.st_issues
            .get_issues([travel_issue_key])
        )[0]
        try:
            link = issue.links.create(
                relationship='relates',
                issue=interconf_issue_key,
                params={'notify': False},
            )
        except BackendError as e:
            if getattr(e, 'status_code', None) == 422:
                link = None
            else:
                raise e

        return link, initiators

    def set_link(self, link, initiators):
        for initiator in initiators:
            initiator['is_issue_link_created'] = True
