# Copyright 2013 the Melange authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Module for the GCI Organization Admins to propose winners for their orgs."""

from google.appengine.ext import db
from google.appengine.ext import ndb

from django import forms
from django.utils.translation import ugettext

from melange.request import access
from melange.request import exception

from soc.modules.gci.views.base import GCIRequestHandler

from soc.views.helper import lists
from soc.views.helper import url_patterns

from soc.modules.gci.logic import organization as org_logic
from soc.modules.gci.logic import org_score as org_score_logic
from soc.modules.gci.models import organization as organization_model
from soc.modules.gci.models import profile as profile_model
from soc.modules.gci.templates import org_list
from soc.modules.gci.views import forms as gci_forms
from soc.modules.gci.views.helper import url_patterns as gci_url_patterns
from soc.modules.gci.views.helper import url_names


DEF_WINNER_MORE_THAN_ONCE_ERROR = ugettext(
    'You cannot set the same winner more than once')

class ProposeWinnersForm(gci_forms.GCIModelForm):
  """Django form to propose the grand prize winners."""

  EMPTY_CHOICE = 'EMPTY_CHOICE'

  class Meta:
    model = None

  def __init__(self, request_data=None, **kwargs):
    super(ProposeWinnersForm, self).__init__(**kwargs)
    self.request_data = request_data

    choices = [(ProposeWinnersForm.EMPTY_CHOICE, '---')]

    possible_winners = org_score_logic.getPossibleWinners(request_data.url_org)

    for possible_winner in possible_winners:
      choices.append(self._getChoiceOption(possible_winner))

    self.fields.get('first_proposed_winner').choices = choices
    self.fields.get('second_proposed_winner').choices = choices
    self.fields.get('backup_proposed_winner').choices = choices

    # check if at least one grand prize winner is already set
    if len(self.request_data.url_org.proposed_winners) > 0:
      self.fields.get('first_proposed_winner').initial = str(
          self.request_data.url_org.proposed_winners[0])

      # check if both grand prize winners are already set
      if len(self.request_data.url_org.proposed_winners) > 1:
        self.fields.get('second_proposed_winner').initial = str(
            self.request_data.organization.proposed_winners[1])

    # check if backup winner is already set
    backup_winner_key = (organization_model.GCIOrganization.backup_winner
        .get_value_for_datastore(self.request_data.url_org))
    if backup_winner_key:
      self.fields.get('backup_proposed_winner').initial = str(backup_winner_key)


  first_proposed_winner = forms.ChoiceField(label='First Grand Prize Winner')
  second_proposed_winner = forms.ChoiceField(label='Second Grand Prize Winner')
  backup_proposed_winner = forms.ChoiceField(label='Backup Grand Prize Winner')

  def clean(self):
    first_proposed_winner = self.cleaned_data.get(
        'first_proposed_winner', ProposeWinnersForm.EMPTY_CHOICE)
    second_proposed_winner = self.cleaned_data.get(
        'second_proposed_winner', ProposeWinnersForm.EMPTY_CHOICE)
    backup_proposed_winner = self.cleaned_data.get(
        'backup_proposed_winner', ProposeWinnersForm.EMPTY_CHOICE)

    # TODO (daniel): the logic below should be simplified
    key_names = set([
        first_proposed_winner, second_proposed_winner, backup_proposed_winner])

    if len(key_names) == 3:
      # there are three different key_names, so everything is OK
      pass
    elif len(key_names) == 2:
      # it is not OK, because at least one of the fields is duplicated
      self._errors['__all__'] = DEF_WINNER_MORE_THAN_ONCE_ERROR
    elif list(key_names)[0] != ProposeWinnersForm.EMPTY_CHOICE:
      # it is not OK, when there is one choice which is not empty
      self._errors['__all__'] = DEF_WINNER_MORE_THAN_ONCE_ERROR

  def _getChoiceOption(self, student):
    return (str(student.key), self._formatPossibleWinner(student))

  def _formatPossibleWinner(self, student):
    return '%s' % student.public_name


class ProposeWinnersPage(GCIRequestHandler):
  """Page to propose winners by organization admins"""

  def templatePath(self):
    return 'modules/gci/propose_winners/base.html'

  def djangoURLPatterns(self):
    return [
        gci_url_patterns.url(r'propose_winners/%s$' % url_patterns.ORG, self,
            name=url_names.GCI_ORG_PROPOSE_WINNERS),
    ]

  def checkAccess(self, data, check, mutator):
    check.isOrgAdminForOrganization(ndb.Key.from_old_key(data.url_org.key()))
    if not data.timeline.allReviewsStopped():
      raise exception.Forbidden(
          message='This page may be accessed when the review period is over')

  def context(self, data, check, mutator):
    form = ProposeWinnersForm(request_data=data, data=data.POST or None)
    context = {
        'page_name': 'Propose winners for %s' % data.url_org.name,
        'forms': [form]