# Copyright (c) 2013 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Sheriff schedule pages."""


import datetime
import json

from google.appengine.ext import db

from base_page import BasePage
import utils


FETCH_LIMIT = 50

HEADER_CONTENT_TYPE = 'Content-Type'
HEADER_ACCESS_CONTROL_ALLOW_ORIGIN = 'Access-Control-Allow-Origin'

JSON_CONTENT_TYPE = 'application/json'
TEXT_CONTENT_TYPE = 'text/plain'


class BaseSheriffs(db.Model):
  """Contains the list of Sheriffs"""
  username = db.StringProperty(required=True)

  @classmethod
  def get_all_sheriffs(cls):
    return cls.all().fetch(limit=FETCH_LIMIT)


class Sheriffs(BaseSheriffs):
  """Contains the list of Skia Sheriffs."""
  pass


class GpuSheriffs(BaseSheriffs):
  """Contains the list of GPU Sheriffs."""
  pass

class Robocops(BaseSheriffs):
  """Contains the list of Android Robocops."""
  pass

class Troopers(BaseSheriffs):
  """Contains the list of Infra Troopers."""
  pass


class BaseSheriffSchedules(db.Model):
  """A single sheriff oncall rotation (one person, one time interval)."""
  schedule_start = db.DateTimeProperty(required=True)
  schedule_end = db.DateTimeProperty(required=True)
  username = db.StringProperty(required=True)

  @classmethod
  def get_upcoming_schedules(cls):
    return (cls.all()
               .filter('schedule_end >', datetime.datetime.now())
               .order('schedule_end')
               .fetch(limit=FETCH_LIMIT))

  @classmethod
  def get_schedules_for_sheriff(cls, sheriff):
    return (cls.all()
               .filter('username =', sheriff)
               .order('schedule_end')
               .fetch(limit=FETCH_LIMIT))

  @classmethod
  def get_current_sheriff(cls):
    current_schedule = cls.all().filter(
        'schedule_end >', datetime.datetime.now()).get()
    if current_schedule:
      return current_schedule.username
    else:
      return 'None'

  @classmethod
  def delete_schedules_after(cls, datetime_obj):
    schedules = cls.all().filter(
        'schedule_end >', datetime_obj).fetch(limit=FETCH_LIMIT)
    for schedule in schedules:
      schedule.delete()

  def AsDict(self, display_year=False):
    data = super(BaseSheriffSchedules, self).AsDict()
    data['username'] = self.username

    date_format = '%m/%d/%y' if display_year else '%m/%d'
    data['schedule_start'] = self.schedule_start.strftime(date_format)
    data['schedule_end'] = self.schedule_end.strftime(date_format)
    return data


class SheriffSchedules(BaseSheriffSchedules):
  """A single Skia sheriff oncall rotation (one person, one time interval)."""
  pass


class GpuSheriffSchedules(BaseSheriffSchedules):
  """A single GPU sheriff oncall rotation (one person, one time interval)."""
  pass

class RobocopSchedules(BaseSheriffSchedules):
  """A single robocop oncall rotation (one person, one time interval)."""
  pass

class TrooperSchedules(BaseSheriffSchedules):
  """A single trooper oncall rotation (one person, one time interval)."""
  pass


class QuerySheriffPage(BasePage):
  """Displays the schedules of the provided sheriff."""

  def get(self):
    self.response.headers[HEADER_CONTENT_TYPE] = JSON_CONTENT_TYPE
    self.response.headers[HEADER_ACCESS_CONTROL_ALLOW_ORIGIN] = '*'

    username = self.request.get('username')
    data = json.dumps({})
    for sheriff in Sheriffs.get_all_sheriffs():
      if sheriff.username.startswith(username):
        schedules = []
        for schedule in SheriffSchedules.get_schedules_for_sheriff(
            sheriff.username):
          schedules.append(schedule.AsDict(display_year=True))
        data = json.dumps({sheriff.username: schedules})
        break

    self.response.out.write(data)


class BaseCurrentSheriffPage(BasePage):
  """BasePage to display the current sheriff and schedule in JSON."""
  @property
  def sheriff_schedules_class(self):
    raise NotImplementedError, "Must be implemented by subclasses."

  def get(self):
    self.response.headers[HEADER_CONTENT_TYPE] = JSON_CONTENT_TYPE
    self.response.headers[HEADER_ACCESS_CONTROL_ALLOW_ORIGIN] = '*'

    upcoming_schedules = self.sheriff_schedules_class.get_upcoming_schedules()
    if upcoming_schedules:
      data = json.dumps(upcoming_schedules[0].AsDict())
    else:
      data = json.dumps({})
    callback = self.request.get('callback')
    if callback:
      data = callback + '(' + data + ')'
    self.response.out.write(data)


class CurrentSheriffPage(BaseCurrentSheriffPage):
  """Displays the current sheriff and schedule in JSON."""
  @property
  def sheriff_schedules_class(self):
    return SheriffSchedules


class CurrentGpuSheriffPage(BaseCurrentSheriffPage):
  """Displays the current GPU sheriff and schedule in JSON."""
  @property
  def sheriff_schedules_class(self):
    return GpuSheriffSchedules


class CurrentRobocopPage(BaseCurrentSheriffPage):
  """Displays the current robocop and schedule in JSON."""
  @property
  def sheriff_schedules_class(self):
    return RobocopSchedules


class CurrentTrooperPage(BaseCurrentSheriffPage):
  """Displays the current trooper and schedule in JSON."""
  @property
  def sheriff_schedules_class(self):
    return TrooperSchedules


class BaseNextSheriffPage(BasePage):
  """BasePage to display the next sheriff and schedule in JSON."""
  @property
  def sheriff_schedules_class(self):
    raise NotImplementedError, "Must be implemented by subclasses."

  def get(self):
    self.response.headers[HEADER_CONTENT_TYPE] = JSON_CONTENT_TYPE
    self.response.headers[HEADER_ACCESS_CONTROL_ALLOW_ORIGIN] = '*'

    upcoming_schedules = self.sheriff_schedules_class.get_upcoming_schedules()
    if upcoming_schedules and len(upcoming_schedules) > 1:
      data = json.dumps(upcoming_schedules[1].AsDict())
    else:
      data = json.dumps({})
    callback = self.request.get('callback')
    if callback:
      data = callback + '(' + data + ')'
    self.response.out.write(data)


class NextSheriffPage(BaseNextSheriffPage):
  """Displays the next sheriff and schedule in JSON."""
  @property
  def sheriff_schedules_class(self):
    return SheriffSchedules


class NextGpuSheriffPage(BaseNextSheriffPage):
  """Displays the next GPU sheriff and schedule in JSON."""
  @property
  def sheriff_schedules_class(self):
    return GpuSheriffSchedules


class NextRobocopPage(BaseNextSheriffPage):
  """Displays the next Android robocop and schedule in JSON."""
  @property
  def sheriff_schedules_class(self):
    return RobocopSchedules


class NextTrooperPage(BaseNextSheriffPage):
  """Displays the next Infra trooper and schedule in JSON."""
  @property
  def sheriff_schedules_class(self):
    return TrooperSchedules


class BaseSheriffPage(BasePage):
  """BasePage to display the list and rotation schedule of all sheriffs."""
  @property
  def sheriff_schedules_class(self):
    raise NotImplementedError, "Must be implemented by subclasses."

  @property
  def sheriff_doc(self):
    raise NotImplementedError, "Must be implemented by subclasses."

  @property
  def sheriff_type(self):
    raise NotImplementedError, "Must be implemented by subclasses."

  @property
  def sheriff_image(self):
    raise NotImplementedError, "Must be implemented by subclasses."

  @utils.require_user
  def get(self):
    template_values = self.InitializeTemplate(
        self.APP_NAME + ' Sheriff Rotation Schedule')

    upcoming_schedules = []
    for upcoming_schedule in (
         self.sheriff_schedules_class.get_upcoming_schedules()):
      schedule_start = upcoming_schedule.schedule_start
      schedule_end = upcoming_schedule.schedule_end
      upcoming_schedule.readable_range = '%s - %s' % (
          schedule_start.strftime('%d %B'), schedule_end.strftime('%d %B'))
      upcoming_schedules.append(upcoming_schedule)

    if upcoming_schedules:
      # The first in the list is the current week.
      upcoming_schedules[0].current_week = True
    # Set the schedules to the template
    template_values['schedules'] = upcoming_schedules
    template_values['sheriff_doc'] = self.sheriff_doc
    template_values['sheriff_type'] = self.sheriff_type
    template_values['sheriff_image'] = self.sheriff_image
    self.DisplayTemplate('sheriffs.html', template_values)


class SheriffPage(BaseSheriffPage):
  """Displays the list and rotation schedule of all sheriffs."""
  @property
  def sheriff_schedules_class(self):
    return SheriffSchedules

  @property
  def sheriff_doc(self):
    return 'https://skia.org/dev/sheriffing'

  @property
  def sheriff_type(self):
    return 'Sheriff'

  @property
  def sheriff_image(self):
    return 'clint.jpg'


class GpuSheriffPage(BaseSheriffPage):
  """Displays the list and rotation schedule of all GPU sheriffs."""
  @property
  def sheriff_schedules_class(self):
    return GpuSheriffSchedules

  @property
  def sheriff_doc(self):
    return 'https://skia.org/dev/sheriffing/gpu'

  @property
  def sheriff_type(self):
    return 'GPU Wrangler'

  @property
  def sheriff_image(self):
    return 'wrangler.jpg'


class RobocopPage(BaseSheriffPage):
  """Displays the list and rotation schedule of all Android robocops."""
  @property
  def sheriff_schedules_class(self):
    return RobocopSchedules

  @property
  def sheriff_doc(self):
    return 'https://skia.org/dev/sheriffing/android'

  @property
  def sheriff_type(self):
    return 'Android Robocop'

  @property
  def sheriff_image(self):
    return 'robocop.jpg'


class TrooperPage(BaseSheriffPage):
  """Displays the list and rotation schedule of all Infra troopers."""
  @property
  def sheriff_schedules_class(self):
    return TrooperSchedules

  @property
  def sheriff_doc(self):
    return 'https://skia.org/dev/sheriffing/trooper'

  @property
  def sheriff_type(self):
    return 'Infra Trooper'

  @property
  def sheriff_image(self):
    return 'trooper.jpg'


class BaseUpdateSheriffsSchedulePage(BasePage):
  """BasePage to set the sheriff schedule."""
  @property
  def sheriff_schedules_class(self):
    raise NotImplementedError, "Must be implemented by subclasses."

  @property
  def sheriff_class(self):
    raise NotImplementedError, "Must be implemented by subclasses."

  @utils.require_user
  def get(self):
    # Read the schedule_start and weeks URL get parameters.
    schedule_start_tokens = self.request.get('schedule_start').split('/')
    schedule_start = datetime.datetime(int(schedule_start_tokens[2]),
                                       int(schedule_start_tokens[0]),
                                       int(schedule_start_tokens[1]))
    weeks = int(self.request.get('weeks'))

    # Get the list of sheriffs from the Sheriffs table.
    sheriffs = []
    for sheriff in self.sheriff_class.get_all_sheriffs():
      sheriffs.append(sheriff.username)

    # Delete all entries greater than the specified start time.
    self.sheriff_schedules_class.delete_schedules_after(schedule_start)

    # Populate the specified weeks with the sheriffs.
    sheriffs_index = 0
    while weeks > 0:
      curr_schedule_end = schedule_start + datetime.timedelta(days=6)
      self.sheriff_schedules_class(
        schedule_start=schedule_start,
        schedule_end=curr_schedule_end,
        username=sheriffs[sheriffs_index]).put()

      # Treat sheriffs like a circular array.
      sheriffs_index = (sheriffs_index + 1) % len(sheriffs)
      # Get the new schedule_start datetime.
      schedule_start = schedule_start + datetime.timedelta(days=7)
      # Decrement the number of weeks left to be filled.
      weeks -= 1


class UpdateSheriffsSchedule(BaseUpdateSheriffsSchedulePage):
  """Sets the sheriff schedule.

  Usage:
    update_sheriffs_schedules?schedule_start=3/11/2013&weeks=10
  The above will populate the schedule for 10 weeks starting on March 11th using
  all the sheriffs in a round robin manner from the Sheriffs table.
  """
  @property
  def sheriff_schedules_class(self):
    return SheriffSchedules

  @property
  def sheriff_class(self):
    return Sheriffs


class UpdateGpuSheriffsSchedule(BaseUpdateSheriffsSchedulePage):
  """Sets the GPU sheriff schedule.

  Usage:
    update_gpu_sheriffs_schedules?schedule_start=3/11/2013&weeks=10
  The above will populate the schedule for 10 weeks starting on March 11th using
  all the sheriffs in a round robin manner from the GPUSheriffs table.
  """
  @property
  def sheriff_schedules_class(self):
    return GpuSheriffSchedules

  @property
  def sheriff_class(self):
    return GpuSheriffs


class UpdateRobocopsSchedule(BaseUpdateSheriffsSchedulePage):
  """Sets the Android robocop schedule.

  Usage:
    update_robocop_schedules?schedule_start=3/11/2013&weeks=10
  The above will populate the schedule for 10 weeks starting on March 11th using
  all the sheriffs in a round robin manner from the Robocops table.
  """
  @property
  def sheriff_schedules_class(self):
    return RobocopSchedules

  @property
  def sheriff_class(self):
    return Robocops


class UpdateTroopersSchedule(BaseUpdateSheriffsSchedulePage):
  """Sets the Infra trooper schedule.

  Usage:
    update_troopers_schedules?schedule_start=3/11/2013&weeks=10
  The above will populate the schedule for 10 weeks starting on March 11th using
  all the sheriffs in a round robin manner from the Troopers table.
  """
  @property
  def sheriff_schedules_class(self):
    return TrooperSchedules

  @property
  def sheriff_class(self):
    return Troopers


class ListSheriffsPage(BasePage):
  """Lists all Skia Sheriffs."""
  def get(self):
    self.response.headers[HEADER_CONTENT_TYPE] = TEXT_CONTENT_TYPE
    self.response.headers[HEADER_ACCESS_CONTROL_ALLOW_ORIGIN] = '*'
    for sheriff in Sheriffs.get_all_sheriffs():
      self.response.out.write(sheriff.username + '\n')


def bootstrap():
  # Guarantee that at least one instance exists.
  for sheriff_class in (Sheriffs, GpuSheriffs, Robocops, Troopers):
    if db.GqlQuery(
        'SELECT __key__ FROM ' + sheriff_class.__name__).get() is None:
      sheriff_class(username='None').put()

  for sheriff_schedules_class in (SheriffSchedules, GpuSheriffSchedules,
                                  RobocopSchedules, TrooperSchedules):
    if db.GqlQuery(
        'SELECT __key__ FROM ' +
        sheriff_schedules_class.__name__).get() is None:
      sheriff_schedules_class(
          schedule_start=datetime.datetime(1970, 1, 1),
          schedule_end=datetime.datetime(1970, 1, 7),
          username='None').put()

