import re

import django

import grouprise.core
import grouprise.features
from grouprise.core import tests
from grouprise.features.associations import models as associations
from grouprise.features.contributions import models as contributions
from grouprise.features.memberships import test_mixins as memberships


def _get_adjusted_event_args(missing_keys=None, **kwargs):
    """ assemble a dictionary of arguments for a new event

    @param missing_keys: keys to be removed from the dictionary
    other keyword arguments: values to be overriden in the default dictionary
    """
    event_args = {'title': 'Some Event', 'text': 'Test Text', 'place': 'Test Place',
                  'time': '3000-01-01 00:00', 'until_time': '3000-01-01 00:00'}
    event_args.update(kwargs)
    for key in (missing_keys or []):
        event_args.pop(key)
    return event_args


class Guest(memberships.MemberMixin, grouprise.core.tests.Test):

    def create_event(self, **kwargs):
        self.client.force_login(self.gestalt.user)
        self.client.post(self.get_url('create-event'), _get_adjusted_event_args(**kwargs))
        self.client.logout()

    def get_event_url(self, title):
        return associations.Association.objects.get(content__title=title).get_absolute_url()

    def create_group_event(self, **kwargs):
        self.client.force_login(self.gestalt.user)
        self.client.post(self.get_url('create-group-event', self.group.slug),
                         _get_adjusted_event_args(**kwargs))
        self.client.logout()

    def test_guest_event_link(self):
        self.assertContainsLink(self.client.get('/'), self.get_url('create-event'))
        self.assertNotContainsLink(
                self.client.get(self.get_url('events')), self.get_url('create-event'))
        self.assertContainsLink(
                self.client.get(self.gestalt.get_absolute_url()), self.get_url('create-event'))
        self.assertNotContainsLink(
                self.client.get(self.group.get_absolute_url()), self.get_url('create-event'))

    def test_guest_create_event(self):
        self.assertLogin(url_name='create-event')
        self.assertLogin(url_name='create-event', method='post')

    def test_guest_create_group_event(self):
        self.assertLogin(url_name='create-group-event', url_args=[self.group.slug])
        self.assertLogin(
                url_name='create-group-event', url_args=[self.group.slug], method='post')

    def test_guest_public_event(self):
        self.create_event(public=True, title='A public Guest Event')
        event_url = self.get_event_url('A public Guest Event')
        self.assertContainsLink(self.client.get('/'), event_url)
        self.assertContainsLink(self.client.get(self.get_url('events')), event_url)
        self.assertContainsLink(self.client.get(self.gestalt.get_absolute_url()), event_url)
        self.assertOk(url=event_url)

    def test_guest_internal_event(self):
        self.create_event(public=False, title='An internal Guest Event')
        event_url = self.get_event_url('An internal Guest Event')
        self.assertNotContainsLink(self.client.get('/'), event_url)
        self.assertNotContainsLink(self.client.get(self.get_url('events')), event_url)
        self.assertNotContainsLink(self.client.get(self.gestalt.get_absolute_url()), event_url)
        self.assertLogin(url=event_url)

    def test_guest_public_group_event(self):
        self.create_group_event(public=True, title='A public Group Guest Event')
        event_url = self.get_event_url('A public Group Guest Event')
        self.assertContainsLink(obj=self.group, link_url=event_url)
        self.assertOk(url=event_url)
        self.assertLogin(url=event_url, method='post')

    def test_guest_internal_group_event(self):
        self.create_group_event(public=False, title='An internal Group Guest Event')
        event_url = self.get_event_url('An internal Group Guest Event')
        self.assertNotContainsLink(obj=self.group, link_url=event_url)
        self.assertLogin(url=event_url)
        self.assertLogin(url=event_url, method='post')


class Gestalt(memberships.AuthenticatedMemberMixin, grouprise.core.tests.Test):

    def create_event(self, **kwargs):
        return self.client.post(self.get_url('create-event'), _get_adjusted_event_args(**kwargs))

    def create_group_event(self, **kwargs):
        return self.client.post(self.get_url('create-group-event', self.group.slug),
                                _get_adjusted_event_args(**kwargs))

    def get_event_url(self, title):
        return associations.Association.objects.get(content__title=title).get_absolute_url()

    def test_gestalt_event_link(self):
        self.assertContainsLink(self.client.get('/'), self.get_url('create-event'))
        self.assertContainsLink(
                self.client.get(self.get_url('events')), self.get_url('create-event'))
        self.assertContainsLink(
                self.client.get(self.gestalt.get_absolute_url()), self.get_url('create-event'))
        self.assertContainsLink(self.client.get(self.group.get_absolute_url()), self.get_url(
            'create-group-event', self.group.slug))

    def test_gestalt_create_event(self):
        self.assertEqual(self.client.get(self.get_url('create-event')).status_code, 200)
        title = 'A new Event'
        response = self.create_event(title=title)
        self.assertRedirects(response, self.get_event_url(title))
        self.assertExists(associations.Association, content__title=title)

    def test_gestalt_create_group_event(self):
        title = 'A new Group Event'
        self.assertEqual(self.client.get(self.get_url(
            'create-group-event', self.group.slug)).status_code, 200)
        response = self.create_group_event(title=title)
        self.assertRedirects(response, self.get_event_url(title))
        self.assertExists(associations.Association, content__title=title)

    def test_gestalt_public_event(self):
        self.create_event(public=True, title='Gestalt Public Event')
        event_url = self.get_event_url('Gestalt Public Event')
        self.assertContainsLink(self.client.get('/'), event_url)
        self.assertContainsLink(self.client.get(self.get_url('events')), event_url)
        self.assertContainsLink(self.client.get(self.gestalt.get_absolute_url()), event_url)
        self.assertOk(url=event_url)

    def test_gestalt_internal_event(self):
        self.create_event(public=False, title='Gestalt Internal Event')
        event_url = self.get_event_url('Gestalt Internal Event')
        self.assertContainsLink(self.client.get('/'), event_url)
        self.assertContainsLink(self.client.get(self.get_url('events')), event_url)
        self.assertContainsLink(self.client.get(self.gestalt.get_absolute_url()), event_url)
        self.assertOk(url=event_url)

    def test_gestalt_public_group_event(self):
        title = 'Public Group Event'
        self.create_group_event(public=True, title=title)
        self.assertContainsLink(obj=self.group, link_url=self.get_event_url(title))
        self.assertOk(url=self.get_event_url(title))

    def test_gestalt_internal_group_event(self):
        self.create_group_event(public=False, title='Gestalt Internal Group Event')
        event_url = self.get_event_url('Gestalt Internal Group Event')
        self.assertContainsLink(obj=self.group, link_url=event_ur
l)
        self.assertOk(url=event_url)

    def test_gestalt_comment_event(self):
        self.create_event(title='Gestalt Comment Event')
        self.assertRedirect(url=self.get_event_url('Gestalt Comment Event'), method='post',
                            data={'text': 'Comment'})
        self.assertExists(contributions.Contribution, text__text='Comment')


class TwoGestalten(
        memberships.OtherMemberMixin, memberships.AuthenticatedMemberMixin,
  
      grouprise.core.tests.Test):

    def create_event(self, **kwargs):
        event_args = _get_adjusted_event_args(**kwargs)
        self.client.post(self.get_url('create-group-event', self.group.slug), event_args)
        self.association = associations.Association.objects.get(content__title=event_args['title'])

    def get_content_u