# Path: dwitter/models.py
# class Dweet(models.Model):
#     code = models.TextField()
#     posted = models.DateTimeField(db_index=True)
#     reply_to = models.ForeignKey("self", on_delete=models.DO_NOTHING,
#                                  related_name="remixes", null=True, blank=True)
# 
#     likes = models.ManyToManyField(User, related_name="liked", blank=True)
#     hotness = models.FloatField(default=1.0, db_index=True)
#     deleted = models.BooleanField(default=False)
# 
#     author = models.ForeignKey(User, on_delete=models.SET(get_sentinel_user),
#                                null=True, blank=True)
# 
#     objects = NotDeletedDweetManager()
#     with_deleted = models.Manager()
# 
#     class Meta:
#         ordering = ('-posted',)
# 
#     def delete(self):
#         self.deleted = True
#         self.save()
# 
#     def save(self, *args, **kwargs):
#         self.calculate_hotness((self.pk is None))
#         super(Dweet, self).save(*args, **kwargs)
# 
#     @cached_property
#     def top_comment(self):
#         """
#         Return the top comment. This is mainly a caching optimization to avoid queries
#         """
#         return self.comments.first()
# 
#     @cached_property
#     def dweet_length(self):
#         return length_of_code(self.code)
# 
#     @cached_property
#     def has_sticky_comment(self):
#         """
#         True when first comment should be stickied (first comment author == dweet author)
#         """
#         if self.top_comment is None:
#             return False
#         return self.top_comment.author == self.author
# 
#     def __str__(self):
#         return 'd/' + str(self.id) + ' (' + self.author.username + ')'
# 
#     def calculate_hotness(self, is_new):
#         """
#         Hotness is inspired by the Hackernews ranking algorithm
#         Read more here:
#         https://medium.com/hacking-and-gonzo/how-hacker-news-ranking-algorithm-works-1d9b0cf2c08d
#         """
#         def epoch_seconds(date):
#             epoch = datetime(2015, 5, 5)  # arbitrary start date before Dwitter existed
#             naive = date.replace(tzinfo=None)
#             td = naive - epoch
#             return td.days * 86400 + td.seconds + (float(td.microseconds) / 1000000)
# 
#         likes = 1
#         if not is_new:
#             likes = max(self.likes.count(), 1)
# 
#         order = log(likes, 2)
#         # 86400 seconds = 24 hours.
#         # So for every log(2) likes on a dweet, its effective
#         # "posted time" moves 24 forward
#         # In other words, it takes log2(likes) * 24hrs before
#         # a dweet with a single like beat yours
#         self.hotness = round(order + epoch_seconds(self.posted)/86400, 7)
# 
# class Comment(models.Model):
#     text = models.TextField()
#     posted = models.DateTimeField()
#     reply_to = models.ForeignKey(Dweet, on_delete=models.CASCADE,
#                                  related_name="comments")
#     author = models.ForeignKey(User, on_delete=models.CASCADE)
# 
#     class Meta:
#         ordering = ('posted',)
# 
#     def __str__(self):
#         return ('c/' +
#                 str(self.id) +
#                 ' (' +
#                 self.author.username +
#                 ') to ' +
#                 str(self.reply_to))


from django import test
from django.urls import reverse
from django.conf import settings
from django.contrib.auth.models import User
from dwitter.models import Dweet, Comment
from django.utils import timezone
from datetime import timedelta
from django.contrib import auth
import importlib


# Some automatic based on
# https://stackoverflow.com/questions/14454001/list-all-suburls-and-check-if-broken-in-python
class UrlsTest(test.TestCase):

    def setUp(self):
        user1 = User.objects.create(username="user1", password="qwertypw")
        user1.set_password('qwertypw')  # Properly hash the password
        user1.save()

        user2 = User.objects.create(username="user2", password="qwertypw")
        user2.set_password('qwertypw')  # Properly hash the password
        user2.save()

        now = timezone.now()

        dweet1 = Dweet.objects.create(id=1,
                                      code="dweet1 code",
                                      posted=now - timedelta(hours=1),
                                      author=user1)

        dweet2 = Dweet.objects.create(id=2,
                                      code="dweet2 code",
                                      posted=now,
                                      reply_to=dweet1,
                                      author=user2)

        dweet2.likes.add(user1, user2)


# Path: dwitter/models.py
# class Dweet(models.Model):
#     code = models.TextField()
#     posted = models.DateTimeField(db_index=True)
#     reply_to = models.ForeignKey("self", on_delete=models.DO_NOTHING,
#                                  related_name="remixes", null=True, blank=True)
# 
#     likes = models.ManyToManyField(User, related_name="liked", blank=True)
#     hotness = models.FloatField(default=1.0, db_index=True)
#     deleted = models.BooleanField(default=False)
# 
#     author = models.ForeignKey(User, on_delete=models.SET(get_sentinel_user),
#                                null=True, blank=True)
# 
#     objects = NotDeletedDweetManager()
#     with_deleted = models.Manager()
# 
#     class Meta:
#         ordering = ('-posted',)
# 
#     def delete(self):
#         self.deleted = True
#         self.save()
# 
#     def save(self, *args, **kwargs):
#         self.calculate_hotness((self.pk is None))
#         super(Dweet, self).save(*args, **kwargs)
# 
#     @cached_property
#     def top_comment(self):
#         """
#         Return the top comment. This is mainly a caching optimization to avoid queries
#         """
#         return self.comments.first()
# 
#     @cached_property
#     def dweet_length(self):
#         return length_of_code(self.code)
# 
#     @cached_property
#     def has_sticky_comment(self):
#         """
#         True when first comment should be stickied (first comment author == dweet author)
#         """
#         if self.top_comment is None:
#             return False
#         return self.top_comment.author == self.author
# 
#     def __str__(self):
#         return 'd/' + str(self.id) + ' (' + self.author.username + ')'
# 
#     def calculate_hotness(self, is_new):
#         """
#         Hotness is inspired by the Hackernews ranking algorithm
#         Read more here:
#         https://medium.com/hacking-and-gonzo/how-hacker-news-ranking-algorithm-works-1d9b0cf2c08d
#         """
#         def epoch_seconds(date):
#             epoch = datetime(2015, 5, 5)  # arbitrary start date before Dwitter existed
#             naive = date.replace(tzinfo=None)
#             td = naive - epoch
#             return td.days * 86400 + td.seconds + (float(td.microseconds) / 1000000)
# 
#         likes = 1
#         if not is_new:
#             likes = max(self.likes.count(), 1)
# 
#         order = log(likes, 2)
#         # 86400 seconds = 24 hours.
#         # So for every log(2) likes on a dweet, its effective
#         # "posted time" moves 24 forward
#         # In other words, it takes log2(likes) * 24hrs before
#         # a dweet with a single like beat yours
#         self.hotness = round(order + epoch_seconds(self.posted)/86400, 7)
# 
# class Comment(models.Model):
#     text = models.TextField()
#     posted = models.DateTimeField()
#     reply_to = models.ForeignKey(Dweet, on_delete=models.CASCADE,
#                                  related_name="comments")
#     author = models.ForeignKey(User, on_delete=models.CASCADE)
# 
#     class Meta:
#         ordering = ('posted',)
# 
#     def __str__(self):
#         return ('c/' +
#                 str(self.id) +
#                 ' (' +
#                 self.author.username +
#                 ') to ' +
#                 str(self.reply_to))


# Path: dwitter/tests/urls/test_all_urls.py
from django import test
from django.urls import reverse
from django.conf import settings
from django.contrib.auth.models import User
from dwitter.models import Dweet, Comment
from django.utils import timezone
from datetime import timedelta
from django.contrib import auth
import importlib



# Some automatic based on
# https://stackoverflow.com/questions/14454001/list-all-suburls-and-check-if-broken-in-python
class UrlsTest(test.TestCase):

    def setUp(self):
        user1 = User.objects.create(username="user1", password="qwertypw")
        user1.set_password('qwertypw')  # Properly hash the password
        user1.save()

        user2 = User.objects.create(username="user2", password="qwertypw")
        user2.set_password('qwertypw')  # Properly hash the password
        user2.save()

        now = timezone.now()

        dweet1 = Dweet.objects.create(id=1,
                                      code="dweet1 code",
                                      posted=now - timedelta(hours=1),
                                      author=user1)

        dweet2 = Dweet.objects.create(id=2,
                                      code="dweet2 code",
                                      posted=now,
                                      reply_to=dweet1,
                                      author=user2)

        dweet2.likes.add(user1, user2)


        Comment.objects.create(id=1,