from __future__ import unicode_literals
from django.db.models.fields.files import ImageFieldFile
from django.test import TestCase, override_settings, Client
from django.utils import timezone
from datetime import timedelta
import factory

from imager_images.models import Photo, Album, CHOICES
from imager_profile.tests import RandomUserFactory


PHOTO_BATCH_SIZE = 14
ALBUM_BATCH_SIZE = 7
USER_BATCH_SIZE = 3
TMP_MEDIA_ROOT = '/tmp/media/'


class PhotoFactory(factory.django.DjangoModelFactory):
    """Creates Photo models for testing."""

    class Meta:
        """Assign Photo model as product of factory."""

        model = Photo

    img_file = factory.django.ImageField(color='blue')


@override_settings(MEDIA_ROOT=TMP_MEDIA_ROOT)
class TestPhotoAndAlbum(TestCase):
    """Album test case."""

    def setUp(self):
        """Setup."""
        self.user1 = RandomUserFactory()
        self.user1.save()
        self.album1 = Album(title='family', owner=self.user1)
        self.album2 = Album(title='friends', owner=self.user1)
        self.photo1 = PhotoFactory.create(title='photo 1',
                                          owner=self.user1)
        self.photo2 = PhotoFactory.create(title='photo 2',  
                                          owner=self.user1)
        self.album1.save()
        self.album2.save()
        self.photo1.save()
        self.photo2.save()
        self.photo1.albums.add(self.album1)

    def test_album_exists(self):
        """Test that when an album is created it is an album."""
        self.assertIsInstance(self.album1, Album)

    def test_photo_exists(self):
        """Test photo has been created."""
        self.assertIsInstance(self.photo1, Photo)

    def test_album_title(self):
        """Test album has title."""
        self.assertEquals(self.album1.title, 'family')

    def test_photo_title(self):
        """Test photo has title."""
        self.assertEquals(self.photo1.title, 'photo 1')

    def test_album_default_description(self):
        """Test album default description is empty string."""
        self.assertEquals(self.album1.description, '')

    def test_photo_default_description(self):
        """Test photo default description is empty string."""
        self.assertEquals(self.photo1.description, '')

    # test photo dates
    def test_photo_uploaded_date(self):
        """Test that the photos uploaded date is working."""
        date_uploaded = self.photo1.date_uploaded
        compare_date = timezone.now()
        self.assertAlmostEqual(date_uploaded, compare_date,
                               delta=timedelta(seconds=10))

    def test_photo_date_modified(self):
        """Test to verify the date changes upon modification of photo."""
        initial = self.photo1.date_modified
        self.assertEquals(initial, self.photo1.date_modified)
        self.photo1.title = 'new title'
        self.photo1.save()
        self.assertNotEqual(initial, self.photo1.date_modified)

    def test_date_published(self):
        """Test that the date published is within acceptable 10 sec."""
        date_published = self.photo1.date_uploaded
        compare_date = timezone.now()
        self.assertAlmostEqual(date_published, compare_date,
                               delta=timedelta(seconds=10))

    def test_photo_published(self):
        """Test that published choices behave as expected."""
        # CHOICES = ['private', 'shared', 'public']
        self.photo1.published = CHOICES[0]
        self.assertEquals(self.photo1.published, 'private')
        self.photo1.published = CHOICES[1]
        self.assertEquals(self.photo1.published, 'shared')
        self.photo1.published = CHOICES[2]
        self.assertEquals(self.photo1.published, 'public')


    # test album dates
    def test_album_created_date(self):
        """Test that the photos uploaded date is working."""
        date_created = self.album1.date_created
        compare_date = timezone.now()
        self.assertAlmostEqual(date_created, compare_date,
                               delta=timedelta(seconds=10))

    def test_album_date_modified(self):
        """Test to verify the date changes upon modification of album."""
        initial = self.photo1.date_modified
        self.assertEquals(initial, self.photo1.date_modified)
        self.photo1.title = 'new title'
        self.photo1.save()
        self.assertNotEqual(initial, self.photo1.date_modified)

    def test_album_date_published(self):
        """Test that album date published is within acceptable 10 sec."""
        self.album1.date_published = timezone.now()
        date_published = self.album1.date_published
        compare_date = timezone.now()
        self.assertAlmostEqual(date_published, compare_date,
                               delta=timedelta(seconds=10))

    def test_album_published(self):
        """Test that album published choices behave as expected."""
        # CHOICES = ['private', 'shared', 'public']
        self.album1.published = CHOICES[0]
        self.assertEquals(self.album1.published, 'private')
        self.album1.published = CHOICES[1]
        self.assertEquals(self.album1.published, 'shared')
        self.album1.published = CHOICES[2]
        self.assertEquals(self.album1.published, 'public')

    def test_photo_in_album(self):
        """Test to verify that photo can be in album."""
        self.assertEquals(self.album1.photos.all()[0], self.photo1)

    def test_photos_have_owner(self):
        """Test to verify that photos have owners."""
        self.assertEquals(self.photo1.owner, self.user1)

    def test_albums_have_owner(self):
        """Test to verify that albums have owners."""
        self.assertEquals(self.album1.owner, self.user1)

    def test_user_has_albums(self):
        """Test to verify that user has albums."""
        self.assertEquals(self.user1.albums.all().count(), 2)

    def test_user_has_photos(self):
        """Test to verify that user has photos."""
        self.assertEquals(self.user1.photos.all().count(), 2)

    def test_photo_has_photo(self):
        """Test to verify photo has been created with an photo."""
        self.assertIsInstance(self.photo1.img_file, ImageFieldFile)


@override_settings(MEDIA_ROOT=TMP_MEDIA_ROOT)
class LibraryViewTests(TestCase):
    """Test the Library view."""

    def setUp(self):
        """Setup."""
        self.client = Client()
        self.user1 = RandomUserFactory.build()
        self.user1.set_password('pirate ninja')
        self.user1.save()
        self.user2 = RandomUserFactory.build()
        self.user2.set_password('blue pineapple')
        self.user2.save()
        self.album1 = Album(title='family', owner=self.user1)
        self.album2 = Album(title='friends', owner=self.user1)
        self.photo1 = PhotoFactory.create(title='photo 1',
                                          owner=self.user1)
        self.photo2 = PhotoFactory.create(title='photo 2',
                                          owner=self.user1)
        self.album3 = Album(title='cats', owner=self.user2)
        self.album4 = Album(title='dogs', owner=self.user2)
        self.photo3 = PhotoFactory.create(title='photo 3',
                                          owner=self.user2)
        self.photo4 = PhotoFactory.create(title='photo 4',
                                          owner=self.user2)
        self.album1.save()
        self.album2.save()
        self.photo1.save()
        self.photo2.save()
        self.photo1.albums.add(self.album1)

        self.album3.save()
        self.album4.save()
        self.photo3.save()
        self.photo4.save()
        self.photo3.albums.add(self.album3)
        self.photo4.albums.add(self.album4)

    def test_login_decorator(self):
        """Test if login decorator behaves as expected."""
        response = self.client.get('/images/library/')
        self.assertEqual(response.status_code, 302)
        self.client.login(username=self.user1.username, password='pirate ninja')
        response = self.client.get('/images/library/')
        self.assertEqual(response.status_code, 200)

    def test_can_see_albums_owned(self):
        """Test if the user can see albums."""
        self.client.login(username=self.user1.username, password='pirate ninja')
        response = self.client.get('/images/library/')
        self.assertEqual(response.context['user'].albums.first().owner.username, self.user1.username)

    def test_user1_no_see_user2_album(self):
        """Test that user1 cannot see user2 albums."""
        self.client.login(username=self.user1.username, password='pirate ninja')
        response = self.client.get('/images/library/')
        self.assertNotIn(self.user2.photos.first().title, response.rendered_content)

    # def test_photo_detail(self):
    #     """Test that you can access if logged in and not if AnonymousUser."""
    #     import pdb; pdb.set_trace()
    #     pk = self.photo4.pk
    #     response = self.client.get('/images/photos/' + str(pk))
    #     self.assertEqual(response.status_code, 301)
    #     self.client.login(username=self.user1.username, password='pirate ninja')
    #     response = self.client.get('/images/photos/' + str(pk))
    #     self.assertEqual(response.status_code, 200)

    # def test_album_detail

    # def test_user1_no_see_user2_photo_detail(self):
    #     """Test that user2 photos do not render on user1 photo page.



