from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals

from .statements import *

nu = datetime.datetime.now()

from rowers.teams import *

class TeamFactory(factory.DjangoModelFactory):
    class Meta:
        model = Team

    name = factory.LazyAttribute(lambda _: faker.word())
    notes = faker.text()
    private = 'open'
    viewing = 'allmembers'


@override_settings(TESTING=True)
class TeamTest(TestCase):
    def setUp(self):
        redis_connection.publish('tasks','KILL')
        self.user_passwords = []
        usernames = [
            'user1',
            'user2',
            'user3',
            'user4',
            'user5',
            'user6',
        ]
        self.users = []
        self.csvfilenames = []

        for i in range(6):
            u = UserFactory(username=usernames[i])
            self.users.append(u)

            r = Rower.objects.create(
                birthdate=faker.profile()['birthdate'],
                gdproptin=True,surveydone=True,
                gdproptindate=timezone.now(),
                rowerplan='coach',
                user=u,
                clubsize=3
            )
            r.save()

            password = faker.word()
            u.set_password(password)
            u.save()
            self.user_passwords.append(password)


            workouts = WorkoutFactory.create_batch(5, user=r)
            for w in workouts:
                self.csvfilenames.append(w.csvfilename)


        self.c = Client()

        self.u = self.users[0]
        self.password = self.user_passwords[0]

        self.t = TeamFactory(manager=self.u)

        # need to set up some requests for testing (they are not good below)
        self.invite = TeamInvite(
            team = self.t,
            user = self.users[1],
            code = 'abcde',
            email = self.users[1].email
            )
        self.invite.save()

        self.rekwest = TeamRequest(
            team = self.t,
            user = self.users[2],
            code ='abcde'
            )
        self.rekwest.save()

    def tearDown(self):
        for csvfilename in self.csvfilenames:
            try:
                os.remove(csvfilename)
            except (IOError, FileNotFoundError,OSError):
                pass

    def test_manager_drop_member(self):
        res = add_member(self.t.id,self.users[1].rower)
        login = self.c.login(username=self.u.username, password = self.password)
        self.assertTrue(login)

        url = '/rowers/me/team/{t}/drop/{u}/'.format(
            t = self.t.id,
            u = self.users[1].id
            )

        response = self.c.get(url,follow=True)
        self.assertEqual(response.status_code,200)
        self.assertRedirects(response,
                             expected_url='/rowers/me/teams/'.format(t=self.t.id),
                             status_code=302,target_status_code=200)

    def test_teamview(self):
        login = self.c.login(username=self.u.username, password = self.password)
        self.assertTrue(login)

        url = '/rowers/team/{t}/'.format(t=self.t.id)
        response = self.c.get(url)
        self.assertEqual(response.status_code, 200)

    def test_teamview_member(self):

        id,comment = add_member(self.t.id,self.users[1].rower)
        self.assertEqual(id,self.t.id)

        login = self.c.login(username=self.users[1].username, password = self.user_passwords[1])
        self.assertTrue(login)

        url = '/rowers/team/{t}/'.format(t=self.t.id)
        response = self.c.get(url)
        self.assertEqual(response.status_code, 200)

    def test_teamsview(self):

        url = '/rowers/me/teams/'

        login = self.c.login(username=self.users[2].username, password = self.user_passwords[2])
        self.assertTrue(login)

        response = self.c.get(url,follow=True)
        self.assertEqual(response.status_code,200)

        html = BeautifulSoup(response.content,'html.parser')
        urls = [a['href'] for a in html.find_all('a')]

        for u in urls:
            if 'rowers' in u and 'http' not in u and 'authorize' not in u and 'import' not in u and 'logout' not in u:
                response = self.c.get(u)
                if response.status_code not in [200,302]:
                    print(url)
                    print(u)
                    print(response.status_code)
                self.assertIn(response.status_code,[200,302])

        login = self.c.login(username=self.users[1].username,
                             password = self.user_passwords[1])
        self.assertTrue(login)

        response = self.c.get(url,follow=True)
        self.assertEqual(response.status_code,200)

        html = BeautifulSoup(response.content,'html.parser')
        urls = [a['href'] for a in html.find_all('a')]

        for u in urls:
            if 'rowers' in u and 'http' not in u and 'authorize' not in u and 'import' not in u and 'logout' not in u:
                response = self.c.get(u)
                if response.status_code not in [200,302]:
                    print(url)
                    print(u)
                    print(response.status_code)
                self.assertIn(response.status_code,[200,302])

    def test_teamsview_manager(self):

        url = '/rowers/me/teams/'

        login = self.c.login(username=self.u,password=self.password)
        self.assertTrue(login)

        response = self.c.get(url,follow=True)
        self.assertEqual(response.status_code,200)

        html = BeautifulSoup(response.content,'html.parser')
        urls = [a['href'] for a in html.find_all('a')]

        for u in urls:
            if 'rowers' in u and 'http' not in u and 'authorize' not in u and 'import' not in u and 'logout' not in u:
                response = self.c.get(u)
                if response.status_code not in [200,302]:
                    print(url)
                    print(u)
                    print(response.status_code)
                self.assertIn(response.status_code,[200,302])

    def test_teamview_member_request(self):

        login = self.c.login(username=self.users[3].username, password = self.user_passwords[3])
        self.assertTrue(login)

        url = '/rowers/team/{t}/requestmembership/{u}/'.format(
            t=self.t.id,
            u=self.users[3].id)

        response = self.c.get(url,follow=True)
        self.assertEqual(response.status_code, 200)

        self.assertRedirects(response,
                             expected_url='/rowers/team/{t}/'.format(t=self.t.id),
                             status_code=302,target_status_code=200)

        login = self.c.login(username=self.users[2].username, password = self.user_passwords[2])
        self.assertTrue(login)

        url = '/rowers/me/request/{id}/revoke/'.format(id=self.rekwest.id)
        self.assertRedirects(response,
                             expected_url='/rowers/team/{t}/'.format(t=self.t.id),
                             status_code=302,target_status_code=200)

        response = self.c.get(url,follow=True)
        self.assertEqual(response.status_code,200)

    def test_teamview_manager_request(self):
        login = self.c.login(username=self.u.username, password = self.password)
        self.assertTrue(login)

        url = '/rowers/me/request/{id}/reject/'.format(id=self.rekwest.id)
        response = self.c.get(url,follow=True)
        self.assertEqual(response.status_code,200)
        self.assertRedirects(response,
                             expected_url='/rowers/me/teams/',
                             status_code=302,target_status_code=200)


    def test_team_invite_view(self):
        login = self.c.login(username=self.u.username, password = self.password)
        self.assertTrue(login)

        url = '/rowers/team/{t}/'.format(t=self.t.id)

        form_data = {
            'email': self.users[1].email,
            'user': u''
            }

        response = self.c.post(url, form_data)
        self.assertEqual(response.status_code, 200)

@override_settings(TESTING=True)
class TeamTestLowLevel(TestCase):
    def setUp(self):
        redis_connection.publish('tasks','KILL')
        self.user_passwords = []
        usernames = [
            'user1',
            'user2',
            'user3',
            'user4',
            'user5',
            'user6',
        ]
        self.users = []
        self.csvfilenames = []

        for i in range(6):
            u = UserFactory(username=usernames[i])
            self.users.append(u)

            r = Rower.objects.create(
                birthdate=faker.profile()['birthdate'],
                gdproptin=True,surveydone=True,
                gdproptindate=timezone.now(),
                rowerplan='coach',
                user=u,
                clubsize=3
            )
            r.save()

            password = faker.word()
            u.set_password(password)
            u.save()
            self.user_passwords.append(password)


            workouts = WorkoutFactory.create_batch(5, user=r)
            for w in workouts:
                self.csvfilenames.append(w.csvfilename)


        self.c = Client()

        self.u = self.users[0]
        self.password = self.user_passwords[0]

        self.t = TeamFactory(manager=self.u)


    def tearDown(self):
        for csvfilename in self.csvfilenames:
            try:
                os.remove(csvfilename)
            except (IOError, FileNotFoundError,OSError):
                pass

    def test_lowlevel_update_team(self):
        id, comment = update_team(self.t,faker.word(),self.u,'open',faker.text(),'allmembers')
        self.assertEqual(id,1)

        id, comment = update_team(self.t,faker.word(),self.users[2],'open',faker.text(),'allmembers')
        self.assertEqual(id,0)

        team = TeamFactory(manager = self.users[2])
        id, comment = update_team(team, self.t.name, self.users[2], 'open', faker.text(),
                                  'allmembers')
        self.assertEqual(id,0)
        self.assertEqual(comment,'Team name duplication')

    def test_lowlevel_create_team(self):
        id, comment = create_team(faker.word(), self.u)
        self.assertEqual(id,2)

        id, comment = create_team(self.t.name,self.u)
        self.assertEqual(id,0)
        self.assertEqual(comment,'Team name duplication')

    def test_lowlevel_remove_team(self):
        team = TeamFactory(manager=self.u)
        tid = team.id
        id, comment = add_member(team.id,self.users[1].rower)
        id, comment = add_member(team.id,self.users[2].rower)

        result = remove_team(team.id)

        test = Team.objects.filter(id=tid)
        self.assertEqual(len(test),0)

    def test_lowlevel_create_request(self):
        id,comment = create_request(self.t,self.users[1].id)
        self.assertEqual(id,1)

    def test_lowlevel_remove_member(self):
        id, comment = add_member(self.t.id, self.users[3].rower)
        id, comment = remove_member(self.t.id, self.users[3].rower)
        self.assertEqual(id, self.t.id)


    def test_lowlevel_create_invite(self):
        id, comment = add_member(self.t.id, self.users[1].rower)

        # cannot create invite for someone who already is a member
        id, comment = create_invite(self.t,self.u,user=self.users[1])
        self.assertEqual(id,0)
        self.assertEqual(comment,'Already member of that team')

        id, comment = remove_member(self.t.id, self.users[1].rower)

        # cannot create invite for team you don't manage
        id, comment = create_invite(self.t, self.users[3],self.users[4])
        self.assertEqual(id,0)
