from __future__ import unicode_literals

from django.db import models
from django.utils import six
from django.utils.translation import ugettext_lazy as _

from reviewboard.diffviewer.models import FileDiff
from reviewboard.reviews.models.base_comment import BaseComment


class Comment(BaseComment):
    """A comment made on a diff.

    A comment can belong to a single filediff or to an interdiff between
    two filediffs. It can also have multiple replies.
    """

    _BASE_FILEDIFF_ID_KEY = '__base_filediff_id'

    anchor_prefix = "comment"
    comment_type = "diff"
    filediff = models.ForeignKey(FileDiff, verbose_name=_('file diff'),
                                 related_name="comments")
    interfilediff = models.ForeignKey(FileDiff,
                                      verbose_name=_('interdiff file'),
                                      blank=True, null=True,
                                      related_name="interdiff_comments")

    # A null line number applies to an entire diff.  Non-null line numbers are
    # the line within the entire file, starting at 1.
    first_line = models.PositiveIntegerField(_("first line"), blank=True,
                                             null=True)
    num_lines = models.PositiveIntegerField(_("number of lines"), blank=True,
                                            null=True)

    last_line = property(lambda self: self.first_line + self.num_lines - 1)

    @property
    def base_filediff_id(self):
        """The ID base FileDiff for the cumulative diff this comment is on."""
        if self.extra_data is None:
            return None

        return self.extra_data.get(self._BASE_FILEDIFF_ID_KEY)

    @base_filediff_id.setter
    def base_filediff_id(self, filediff_id):
        if self.extra_data is None:
            self.extra_data = {}

        self.extra_data[self._BASE_FILEDIFF_ID_KEY] = filediff_id

    def get_absolute_url(self):
        revision_path = six.text_type(self.filediff.diffset.revision)
        if self.interfilediff:
            revision_path += "-%s" % self.interfilediff.diffset.revision

        return "%sdiff/%s/?file=%s#file%sline%s" % (
            self.get_review_request().get_absolute_url(),
            revision_path, self.filediff.id, self.filediff.id,
            self.first_line)

    class Meta(BaseComment.Meta):
        db_table = 'reviews_comment'
        verbose_name = _('Diff Comment')
        verbose_name_plural = _('Diff Comments')