from django.db import models
from django.utils.translation import ugettext_lazy as _
from uuidfield import UUIDField


class ClassMethodMixin(object):
    """Mixin for commonly used class methods on models"""

    @classmethod
    def get_class_name(cls):
        value = cls.__name__.lower()
        return value


class TimeStampedModel(models.Model):
    """A simple mixin to timestamp models that inherit from it"""

    class Meta:
        abstract = True

    created_on = models.DateTimeField(
        _('Created on'),
        auto_now_add=True,
        editable=False
    )
    last_modified = models.DateTimeField(
        _('Last modified'),
        db_index=True,
        auto_now=True,
        editable=False
    )


class UUIDModel(models.Model):
    """A simple mixin to add a uuid to models that inherit from it"""

    class Meta:
        abstract = True

    uuid = UUIDField(
        db_index=True,
        auto=True
    )


class PeriodStartModel(models.Model):
    class Meta:
        abstract = True

    period_start = models.DateField(
        _('Period start'),
        help_text=_('The start date for this %(class)s'),
        null=True,
        blank=True
    )

    #TODO: Move period method here
    # if hass attr period_end, elif get other models in future from period_start, else period is til now.
    # then this method will work with classes that subclass this class.


class PeriodicModel(PeriodStartModel):

    class Meta:
        abstract = True

    period_end = models.DateField(
        _('Period end'),
        help_text=_('The end date for this %(class)s')
    )

    #TODO: implement a shortcut from period_start/end to year
    @property
    def period(self):
        # TODO: Write a smarter method for the general use case
        # naive, just for current purposes
        tmp = self.period_end - self.period_start
        if tmp.days <= 365:
            return self.period_start.year
        else:
            return unicode(self.period_start.year) + ' - ' + self.period_end.year

from django.db import models
from django.utils.translation import ugettext_lazy as _
from uuidfield import UUIDField
from openbudget.settings import base as settings


class ClassMethodMixin(object):
    """A mixin for commonly used classmethods on models."""

    @classmethod
    def get_class_name(cls):
        value = cls.__name__.lower()
        return value


class TimeStampedModel(models.Model):
    """A mixin to add timestamps to models that inherit it."""

    created_on = models.DateTimeField(
        _('Created on'),
        db_index=True,
        auto_now_add=True,
        editable=False
    )
    last_modified = models.DateTimeField(
        _('Last modified'),
        db_index=True,
        auto_now=True,
        editable=False
    )

    class Meta:
        abstract = True


class UUIDModel(models.Model):
    """A mixin to add UUIDs to models that inherit it."""

    uuid = UUIDField(
        db_index=True,
        auto=True
    )

    class Meta:
        abstract = True


class PeriodStartModel(models.Model):
    """A mixin to add a period_start field to models that inherit it.

    The primary use of this mixin is for model objects with data that applies
    over a period of time, and where the applicable period is only determined by
    the presence of another object with a future-dated value for period_start.

    Example: CBS data (valid until the next dataset), official budget template for
    municipalities in Israel (valid until a new template will come to
    replace/extend the existing one.)
    """

    period_start = models.DateField(
        _('Period start'),
        db_index=True,
        null=True,
        blank=True,
        help_text=_('The start date for this %(class)s'),
    )

    class Meta:
        abstract = True

    # TODO: Implement a period method here.
    # However, we do not currently have a use case for it.


class PeriodicModel(PeriodStartModel):
    """A mixin to add a defined period of validity to models that inherit it."""

    period_end = models.DateField(
        _('Period end'),
        db_index=True,
        null=True,
        blank=True,
        help_text=_('The end date for this %(class)s')
    )

    @property
    def period(self):
        """Get the applicable period for this object."""

        # TODO: Support ranges other than yearly, including multiple ranges.

        value = None
        ranges = settings.OPENBUDGET_PERIOD_RANGES

        if len(ranges) == 1 and 'yearly' in ranges:
            value = self.period_start.year
        else:
            # TODO: Verify - in the current codebase, we should never get here.
            pass

        return value

    class Meta:
        abstract = True

Refactor and cleanup model mixins.