# Copyright (c) 2012 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.

"""Status management pages."""

from contextlib import closing

import base64
import datetime
import json
import logging
import re
import urllib2

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

from base_page import BasePage
from sheriff import SheriffSchedules
import utils


OPEN_STATE = 'open'
CAUTION_STATE = 'caution'
CLOSED_STATE = 'closed'

# The maximum chunk of statuses that are displayed.
MAX_STATUS_CHUNK = 1000
# The default chunk of statuses that are displayed.
DEFAULT_STATUS_CHUNK = 25

CHROMIUM_DEPS_FILE = (
    'https://chromium.googlesource.com/chromium/src/+/master/DEPS?format=TEXT')


class Status(db.Model):
  """Description for the status table."""
  # The username who added this status.
  username = 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)

  @property
  def general_state(self):
    """Returns a string representing the state that the status message
    describes.
    """
    if re.search(CLOSED_STATE, self.message, re.IGNORECASE):
      return CLOSED_STATE
    elif re.search(CAUTION_STATE, self.message, re.IGNORECASE):
      return CAUTION_STATE
    else:
      return OPEN_STATE

  @staticmethod
  def validate_state_message(message):
    """Throws an Error iff exactly one of closed, open or caution is missing."""
    closed_state = re.search(CLOSED_STATE, message, re.IGNORECASE)
    caution_state = re.search(CAUTION_STATE, message, re.IGNORECASE)
    open_state = re.search(OPEN_STATE, message, re.IGNORECASE)
    if (closed_state and open_state) or (
        closed_state and caution_state) or (
        caution_state and open_state):
      raise ValueError(
          'Cannot specify two keywords from (\'%s\', \'%s\', \'%s\') in a '
          'status message!' % (CLOSED_STATE, CAUTION_STATE, OPEN_STATE))
    elif not (closed_state or caution_state or open_state):
      raise ValueError(
          'Must specify either \'%s\' or \'%s\' or \'%s\' somewhere in the '
          'status message!' % (CLOSED_STATE, CAUTION_STATE, OPEN_STATE))

  @property
  def can_commit_freely(self):
    return (self.general_state == OPEN_STATE or
            self.general_state == CAUTION_STATE)

  def AsDict(self):
    data = super(Status, self).AsDict()
    data['general_state'] = self.general_state
    data['can_commit_freely'] = self.can_commit_freely
    return data


def get_status():
  """Returns the current Status, e.g. the most recent one."""
  status = memcache.get('last_status')
  if status is None:
    status = Status.all().order('-date').get()
    # Use add instead of set(); must not change it if it was already set.
    memcache.add('last_status', status)
  return status


def put_status(status):
  """Sets the current Status, e.g. append a new one."""
  prev_status = memcache.get('last_status')
  if prev_status is None:
    prev_status = Status.all().order('-date').get()
  prev_status.put()
  # Now add the new status.
  status.put()

  # Flush the cache.
  memcache.flush_all()
  memcache.set('last_status', status)
  memcache.delete('last_statuses')


def get_last_statuses(limit):
  """Returns the last |limit| statuses."""
  statuses = memcache.get('last_statuses')
  if not statuses or len(statuses) < limit:
    statuses = Status.all().order('-date').fetch(limit)
    memcache.add('last_statuses', statuses)
  return statuses[:limit]


def parse_date(date):
  """Parses a date."""
  match = re.match(r'^(\d\d\d\d)-(\d\d)-(\d\d)$', date)
  if match:
    return datetime.datetime(
        int(match.group(1)), int(match.group(2)), int(match.group(3)))
  if date.isdigit():
    return datetime.datetime.utcfromtimestamp(int(date))
  return None


class AllStatusPage(BasePage):
  """Displays a big chunk, equal to MAX_CHUNK of status values."""
  def get(self):
    query = db.Query(Status).order('-date')
    start_date = self.request.get('startTime')
    if start_date:
      query.filter('date <', parse_date(start_date))
    try:
      limit = int(self.request.get('limit'))
    except ValueError:
      limit = MAX_STATUS_CHUNK
    end_date = self.request.get('endTime')
    beyond_end_of_range_status = None
    if end_date:
      query.filter('date >=', parse_date(end_date))
      # We also need to get the very next status in the range, otherwise
      # the caller can't tell what the effective tree status was at time
      # |end_date|.
      beyond_end_of_range_status = Status.all(
          ).filter('date <', end_date).order('-date').get()

    out_format = self.request.get('format', 'csv')
    if out_format == 'csv':
      # It's not really an html page.
      self.response.headers['Content-Type'] = 'text/plain'
      template_values = self.InitializeTemplate(self.APP_NAME + ' Tree Status')
      template_values['status'] = query.fetch(limit)
      template_values['beyond_end_of_range_status'] = beyond_end_of_range_status
      self.DisplayTemplate('allstatus.html', template_values)
    elif out_format == 'json':
      self.response.headers['Content-Type'] = 'application/json'
      self.response.headers['Access-Control-Allow-Origin'] = '*'
      statuses = [s.AsDict() for s in query.fetch(limit)]
      if beyond_end_of_range_status:
        statuses.append(beyond_end_of_range_status.AsDict())
      data = json.dumps(statuses)
      callback = self.request.get('callback')
      if callback:
        if re.match(r'^[a-zA-Z$_][a-zA-Z$0-9._]*$', callback):
          data = '%s(%s);' % (callback, data)
      self.response.out.write(data)
    else:
      self.response.headers['Content-Type'] = 'text/plain'
      self.response.out.write('Invalid format')


class LkgrPage(BasePage):
  """Displays Skia's LKGR.

  Parses Chromium's DEPS file to get this information. The justification for
  this is that a Skia rev makes it into Chromium after passing all required
  tests.
  """

  def get(self):
    """Displays Skia's LKGR."""
    try:
      with closing(urllib2.urlopen(CHROMIUM_DEPS_FILE)) as f:
        chromium_deps = base64.b64decode(f.read())
      if 'skia_revision' in chromium_deps:
        skia_lkgr = re.search(
            r'.*\'skia_revision\': \'(?P<revision>[0-9a-fA-F]{2,40})\'.*',
            chromium_deps).group('revision')
      else:
        raise Exception('Could not find skia_revision!')
    except Exception, e:
      skia_lkgr = -1
      logging.error(e)
    self.response.out.write(skia_lkgr)


class BannerStatusPage(BasePage):
  """Displays the /current page."""

  def get(self):
    """Displays the current message and nothing else."""
    out_format = self.request.get('format', 'html')
    status = get_status()
    if out_format == 'raw':
      self.response.headers['Content-Type'] = 'text/plain'
      self.response.out.write(status.message)
    elif out_format == 'json':
      self.response.headers['Content-Type'] = 'application/json'
      if self.request.get('with_credentials'):
        self.response.headers['Access-Control-Allow-Origin'] = (
            'gerrit-int.chromium.org, gerrit.chromium.org')
        self.response.headers['Access-Control-Allow-Credentials'] = 'true'
      else:
        self.response.headers['Access-Control-Allow-Origin'] = '*'
      data = json.dumps(status.AsDict())
      callback = self.request.get('callback')
      if callback:
        if re.match(r'^[a-zA-Z$_][a-zA-Z$0-9._]*$', callback):
          data = '%s(%s);' % (callback, data)
      self.response.out.write(data)
    elif out_format == 'html':
      template_values = self.InitializeTemplate(self.APP_NAME + ' Tree Status')
      template_values['message'] = status.message
      template_values['state'] = status.general_state
      template_values['sheriff'] = SheriffSchedules.get_current_sheriff()
      self.DisplayTemplate('current.html', template_values, use_cache=True)
    else:
      self.error(400)


class BinaryStatusPage(BasePage):
  """Displays the /binarystatus page."""

  def get(self):
    """Displays 1 if the tree is open or in caution, and 0 if it is closed."""
    status = get_status()
    self.response.headers['Cache-Control'] = 'no-cache, private, max-age=0'
    self.response.headers['Content-Type'] = 'text/plain'
    self.response.out.write(str(int(status.can_commit_freely)))

  @utils.admin_only
  def post(self):
    """Adds a new message from a backdoor.

    The main difference with MainPage.post() is that it doesn't look for
    conflicts and doesn't redirect to /.
    """
    message = self.request.get('message')
    username = self.request.get('username')
    if message and username:
      put_status(Status(message=message, username=username))
    self.response.out.write('OK')


class MainPage(BasePage):
  """Displays the main page containing the last DEFAULT_STATUS_CHUNK msgs."""

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

  def _handle(self, error_message='', last_message=''):
    """Sets the information to be displayed on the main page."""
    try:
      limit = min(max(int(self.request.get('limit')), 1), MAX_STATUS_CHUNK)
    except ValueError:
      limit = DEFAULT_STATUS_CHUNK
    status = get_last_statuses(limit)
    current_status = get_status()
    if not last_message:
      last_message = current_status.message

    template_values = self.InitializeTemplate(self.APP_NAME + ' Tree Status')
    template_values['status'] = status
    template_values['message'] = last_message
    template_values['last_status_key'] = current_status.key()
    template_values['error_message'] = error_message
    template_values['default_status_chunk'] = DEFAULT_STATUS_CHUNK
    self.DisplayTemplate('main.html', template_values)

  @utils.require_user
  @utils.admin_only
  def post(self):
    """Adds a new message."""
    # We pass these variables back into get(), prepare them.
    last_message = ''
    error_message = ''

    # Get the posted information.
    new_message = self.request.get('message')
    last_status_key = self.request.get('last_status_key')
    if not new_message:
      # A submission contained no data. It's a better experience to redirect
      # in this case.
      self.redirect("/")
      return

    # Ensure the new status message contains exactly one of 'open' or 'closed'
    # or 'caution'.
    try:
      Status.validate_state_message(new_message)
    except ValueError, e:
      error_message = e.message
      return self._handle(e.message, new_message)

    current_status = get_status()
    if current_status and (last_status_key != str(current_status.key())):
      error_message = ('Message not saved, mid-air collision detected, '
                       'please resolve any conflicts and try again!')
      last_message = new_message
      return self._handle(error_message, last_message)
    else:
      put_status(Status(message=new_message, username=self.user.email()))
      self.redirect("/")


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