# 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.

"""Builder Status management pages."""


import json
import time

from google.appengine.api import memcache
from google.appengine.ext import db

from base_page import BasePage
import utils


# The default number of builder status messages that are displayed.
DEFAULT_BUILDER_STATUS_CHUNK = 500


class BuilderStatus(db.Model):
  """Description for each builder."""
  # The username who added this status.
  username = db.StringProperty(required=True)
  # The builder the status message applies to.
  builder_name = db.StringProperty(required=True)
  # The date when the status got added.
  date = db.DateTimeProperty(auto_now_add=True)
  # The message. It can contain html code.
  message = db.StringProperty(required=True)

  @classmethod
  def delete_builder(cls, builder_name):
    builders = cls.all().filter('builder_name =', builder_name).fetch(limit=1)
    if builders:
      builders[0].delete()

  @classmethod
  def get_status_for_builder(cls, builder_name):
    builders = (BuilderStatus.all()
                             .filter('builder_name =', builder_name)
                             .fetch(limit=1))
    return builders[0].message if builders else ''


def get_builder_statuses():
  """Returns all builder statuses."""
  builder_statuses = memcache.get('builder_statuses')
  if not builder_statuses:
    builder_statuses = BuilderStatus.all().order('-date').fetch(
        DEFAULT_BUILDER_STATUS_CHUNK)
    memcache.add('builder_statuses', builder_statuses)
  return builder_statuses


class GetBuilderStatusesPage(BasePage):
  """Returns a JSON of all builder statuses."""

  def get(self):
    builder_statuses = get_builder_statuses()
    builder_dict = {}
    for status in builder_statuses:
      tmp_dict = {}
      tmp_dict['message'] = status.message
      tmp_dict['date'] = str(status.date)
      tmp_dict['username'] = status.username
      builder_dict[status.builder_name] = tmp_dict
    html_output = json.dumps(builder_dict, sort_keys=True)
    callback = self.request.get('callback')
    if callback:
      html_output = callback + '(' + html_output + ')'
    self.response.headers['Content-Type'] = 'application/json'
    self.response.out.write(html_output)


class BuilderStatusPage(BasePage):
  """Displays the builder status page containing msgs for some builders."""

  @utils.require_user
  def get(self):
    return self._handle()

  @utils.require_user
  @utils.admin_only
  def post(self):
    """Adds a new builder status message."""

    # Check if this is a delete builder request.
    delete_builder = self.request.get('delete')
    if delete_builder:
      BuilderStatus.delete_builder(delete_builder)
    else:
      message = self.request.get('message')
      builder_name = self.request.get('builder_name')
      # If an entry with the builder_name already exists then delete it first.
      BuilderStatus.delete_builder(builder_name)

      # Add a new BuilderStatus entry.
      BuilderStatus(username=self.user.email(),
                    builder_name=builder_name,
                    message=message).put()

    # Flush the cache.
    memcache.flush_all()
    memcache.delete('builder_statuses')
    # Wait for a second before accessing the memcache again (in case there is a
    # propagation delay).
    time.sleep(1)
    # Set template values and load the template.
    self._handle()

  def _handle(self):
    """Sets the information to be displayed on the builder status page."""
    builder_statuses = get_builder_statuses()

    template_values = self.InitializeTemplate('Builder Statuses')
    template_values['builder_statuses'] = builder_statuses
    selected_builder_name = self.request.get('selected_builder_name')
    template_values['selected_builder_name'] = selected_builder_name
    if selected_builder_name:
      template_values['selected_builder_status'] = (
          BuilderStatus.get_status_for_builder(selected_builder_name))
    self.DisplayTemplate('builder_status.html', template_values)


def bootstrap():
  # Guarantee that at least one instance exists.
  if db.GqlQuery('SELECT __key__ FROM BuilderStatus').get() is None:
    BuilderStatus(username='none', builder_name='TestBuilder',
           message='welcome to status').put()

