#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright 2008-2012 Zuza Software Foundation
#
# This file is part of translate.
#
# translate is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# translate is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with translate; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

import locale

from django.contrib.auth.models import User, UserManager, AnonymousUser
from django.db import models
from django.db.models import Q
from django.db.models.signals import post_save
from django.utils.html import simple_email_re as email_re
from django.utils.translation import ugettext_lazy as _

from pootle.i18n.override import lang_choices
from pootle_misc.baseurl import l
from pootle_misc.util import cached_property

from translate.misc.hash import md5_f


class PootleUserManager(UserManager):
    """A manager class which is meant to replace the manager class for the User
    model. This manager hides the 'nobody' and 'default' users for normal
    queries, since they are special users. Code that needs access to these
    users should use the methods get_default_user and get_nobody_user.
    """
    def get_default_user(self):
        return super(PootleUserManager, self).get_query_set() \
                                             .select_related(depth=1) \
                                             .get(username='default')

    def get_nobody_user(self):
        return super(PootleUserManager, self).get_query_set() \
                                             .select_related(depth=1) \
                                             .get(username='nobody')

    def hide_defaults(self):
        return super(PootleUserManager, self).get_query_set().exclude(
                username__in=('nobody', 'default')
            )


# Since PootleUserManager has no state, we can just replace the User manager's
# class with PootleUserManager to get the desired functionality.
User.objects.__class__ = PootleUserManager


class PootleProfileManager(models.Manager):
    def get_query_set(self):
        return super(PootleProfileManager, self).get_query_set() \
                                                .select_related('alt_src_langs')

    def get_by_natural_key(self, username):
        return self.get(user__username=username)


class PootleProfile(models.Model):
    objects = PootleProfileManager()

    class Meta:
        db_table = 'pootle_app_pootleprofile'

    # This is the only required field
    user = models.OneToOneField(User, unique=True, db_index=True)

    unit_rows = models.SmallIntegerField(default=9,
            verbose_name=_("Number of Rows"))
    input_height = models.SmallIntegerField(default=5, editable=False)

    # TODO: Remove these two fields once bug 2652 has been fixed
    languages = models.ManyToManyField('pootle_language.Language', blank=True,
            limit_choices_to=~Q(code='templates'),
            related_name="user_languages", verbose_name=_("Languages"),
            db_index=True)
    projects = models.ManyToManyField('pootle_project.Project', blank=True,
            db_index=True, verbose_name=_("Projects"))

    ui_lang = models.CharField(max_length=50, blank=True, null=True,
            choices=(choice for choice in lang_choices()),
            verbose_name=_('Interface Language'))
    alt_src_langs = models.ManyToManyField('pootle_language.Language',
            blank=True, db_index=True, limit_choices_to=~Q(code='templates'),
            related_name="user_alt_src_langs",
            verbose_name=_("Alternative Source Languages"))

    def natural_key(self):
        return (self.user.username,)
    natural_key.dependencies = ['auth.User']

    def __unicode__(self):
        username = self.user.username

        if email_re.match(username):
            username = username.strip().rsplit('@', 1)[0]

        return username

    def get_absolute_url(self):
        return l('/accounts/%s/' % self.user.username)

    @cached_property
    def get_email_hash(self):
        return md5_f(self.user.email).hexdigest()

    def gravatar_url(self, size=80):
        if not self.get_email_hash:
            return ''

        return 'http://www.gravatar.com/avatar/%s?s=%d&d=mm' % \
            (self.get_email_hash, size)

    isopen = property(lambda self: True)

    def _get_pootle_user(self):
        if self.user_id is not None:
            return self.user
        else:
            return AnonymousUser()
    pootle_user = property(_get_pootle_user)

    def get_unit_rows(self):
        return min(max(self.unit_rows, 5), 49)

    def getuserstatistics(self):
        """Get user statistics for user statistics links."""
        userstatistics = []

        userstatistics.append({
            'text': _('Suggestions Accepted'),
            'count': self.suggester.filter(state='accepted').count()
        })
        userstatistics.append({
            'text': _('Suggestions Pending'),
            'count': self.suggester.filter(state='pending').count()
        })
        userstatistics.append({
            'text': _('Suggestions Reviewed'),
            'count': self.reviewer.count()
        })
        userstatistics.append({
            'text': _('Submissions Made'),
            'count': self.submission_set.count()
        })

        return userstatistics


def create_pootle_profile(sender, instance, **kwargs):
    """A post-save hook for the User model which ensures that it gets an
    associated PootleProfile.
    """
    try:
        profile = instance.get_profile()
    except PootleProfile.DoesNotExist:
        profile = PootleProfile(user=instance)
        profile.save()


post_save.connect(create_pootle_profile, sender=User)


def get_profile(user):
    """Return the PootleProfile associated with a user.

    This function is only necessary if 'user' could be an anonymous
    user.  If you know for certain that a user is logged in, then use
    the .get_profile() method on a user instead.
    """
    if user.is_authenticated():
        # Return the PootleProfile associated with authenticated users
        return user.get_profile()
    else:
        # Anonymous users get the PootleProfile associated with the 'nobody'
        # user
        return User.objects.get(username='nobody').get_profile()
