# Copyright 2008 Google Inc.
#
# 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.

"""Views for Gerrit.

This requires Django 0.97.pre.
"""


### Imports ###


# Python imports
import os
import cgi
import random
import re
import logging
import binascii
import datetime
import hashlib
import zlib
from xml.etree import ElementTree
from cStringIO import StringIO

# AppEngine imports
from google.appengine.api import mail
from google.appengine.api import memcache
from google.appengine.api import users
from google.appengine.ext import db
from google.appengine.ext.db import djangoforms

# Django imports
# TODO(guido): Don't import classes/functions directly.
from django import forms
from django import http
from django.http import HttpResponse, HttpResponseRedirect
from django.http import HttpResponseForbidden, HttpResponseNotFound
from django.shortcuts import render_to_response
import django.template
from django.utils import simplejson
from django.forms import formsets

# Local imports
from memcache import Key as MemCacheKey
import models
import email
import engine
import library
import patching
import fields
import project
import git_models
from view_util import *


### Constants ###

MAX_ROWS = 1000


### Helper functions ###


def _random_bytes(n):
  """Helper returning a string of random bytes of given length."""
  return ''.join(map(chr, (random.randrange(256) for i in xrange(n))))


### Request handlers ###


def index(request):
  """/ - Show a list of patches."""
  if request.user is None:
    return all(request)
  else:
    return mine(request)


DEFAULT_LIMIT = 10

def all(request):
  """/all - Show a list of up to DEFAULT_LIMIT recent change."""
  offset = request.GET.get('offset')
  if offset:
    try:
      offset = int(offset)
    except:
      offset = 0
    else:
      offset = max(0, offset)
  else:
    offset = 0
  limit = request.GET.get('limit')
  if limit:
    try:
      limit = int(limit)
    except:
      limit = DEFAULT_LIMIT
    else:
      limit = max(1, min(limit, 100))
  else:
    limit = DEFAULT_LIMIT
  query = db.GqlQuery('SELECT * FROM Change '
                      'WHERE closed = FALSE ORDER BY modified DESC')
  # Fetch one more to see if there should be a 'next' link
  changes = query.fetch(limit+1, offset)
  more = bool(changes[limit:])
  if more:
    del changes[limit:]
  if more:
    next = '/all?offset=%d&limit=%d' % (offset+limit, limit)
  else:
    next = ''
  if offset > 0:
    prev = '/all?offset=%d&limit=%d' % (max(0, offset-limit), limit)
  else:
    prev = ''
  newest = ''
  if offset > limit:
    newest = '/all?limit=%d' % limit

  _optimize_draft_counts(changes)
  _prefetch_names(changes)
  return respond(request, 'all.html',
                 {'changes': changes, 'limit': limit,
                  'newest': newest, 'prev': prev, 'next': next,
                  'first': offset+1,
                  'last': len(changes) > 1 and offset+len(changes) or None})


def _optimize_draft_counts(changes):
  """Force _num_drafts to zero for changes that are known to have no drafts.

  Args:
    changes: list of model.Change instances.

  This inspects the drafts attribute of the current user's Account
  instance, and forces the draft count to zero of those changes in the
  list that aren't mentioned there.

  If there is no current user, all draft counts are forced to 0.
  """
  account = models.Account.current_user_account
  if account is None:
    change_ids = None
  else:
    change_ids = account.drafts
  for change in changes:
    if change_ids is None or change.key().id() not in change_ids:
      change._num_drafts = 0

def _prefetch_names(changes):
  for c in changes:
    library.prefetch_names([c.owner])
    library.prefetch_names(c.reviewers)
    library.prefetch_names(c.cc)


@login_required
def mine(request):
  """/mine - Show a list of changes created by the current user."""
  request.user_to_show = request.user
  return _show_user(request)

def unclaimed_project_memcache_key(user):
  return "user_unclaimed_projects:%s" % user.email()

def all_unclaimed(request):
  flat_changes = models.gql(models.Change,
                          ' WHERE closed = FALSE'
                          '   AND claimed = FALSE'
                          ' ORDER BY dest_project DESC,'
                          '   modified DESC').fetch(1000)
  changes = []
  c_list = []
  last_project_key = None
  for c in flat_changes:
    logging.info("c=" + str(c))
    k = c.dest_project.key()
    if k != last_project_key:
      if c_list:
        _optimize_draft_counts(c_list)
        _prefetch_names(c_list)
        changes.append({
            'name': c.dest_project.name,
            'changes': c_list,
          })
      last_project_key = k
      c_list = []
    c_list.append(c)
  if c_list:
    _optimize_draft_counts(c_list)
    _prefetch_names(c_list)
    changes.append({
        'name': c.dest_project.name,
        'changes': c_list,
      })
  vars = {
      'projects': changes,
    }

  return respond(request, 'unclaimed.html', vars)

@login_required
def unclaimed(request):
  """/unclaimed - Show changes with no reviewer listed for user's selected
  projects."""
  def _get_unclaimed_projects(user):
    memcache_key = unclaimed_project_memcache_key(user)
    keys = memcache.get(memcache_key)
    if keys is None:
      account = models.Account.get_account_for_user(user)
      keys = account.unclaimed_changes_projects
      err = memcache.set(memcache_key, keys)
    result = models.Project.get(keys)
    if not result:
      result = []
    return result

  user = request.user
  changes = []

  projects = _get_unclaimed_projects(request.user)
  for project in projects:
    c = models.gql(models.Change,
                          ' WHERE closed = FALSE'
                          '   AND claimed = FALSE'
                          '   AND dest_project = :dest_project'
                          ' ORDER BY modified DESC',
                          dest_project=project.key()).fetch(1000)
    if c:
      _optimize_draft_counts(c)
      _prefetch_names(c)
      changes.append({
          'name': project.name,
          'changes': c,
        })

  vars = {
      'projects': changes,
    }

  return respond(request, 'unclaimed.html', vars)


@login_required
def starred(request):
  """/starred - Show a list of changes starred by the current user."""
  stars = models.Account.current_user_account.stars
  if not stars:
    changes = []
  else:
    changes = [change for change in models.Change.get_by_id(stars)
                    if change is not None]
    _optimize_draft_counts(changes)
    _prefetch_names(changes)
  return respond(request, 'starred.html', {'changes': changes})


@user_key_required
def show_user(request):
  """/user - Show the user's dashboard"""
  return _show_user(request)

@user_key_required
def ajax_user_mine(request, offset_str):
  m = _user_mine(request, request.user_to_show, int(offset_str))
  return _respond_paged(request,'change_pagedrow.html',
                        'change', 'mine', m)

@user_key_required
def ajax_user_review(request, offset_str):
  m = _user_review(request, request.user_to_show, int(offset_str))
  return _respond_paged(request,'change_pagedrow.html',
                        'change', 'review', m)

@user_key_required
def ajax_user_closed(request, offset_str):
  m = _user_closed(request, request.user_to_show, int(offset_str))
  return _respond_paged(request,'change_pagedrow.html',
                        'change', 'closed', m)

def _respond_paged(request, template, new_pfx, old_pfx, vars):
  return respond(request, template, {
                 new_pfx + '_list': vars[old_pfx + '_list'],
                 new_pfx + '_opos': vars[old_pfx + '_opos'],
                 new_pfx + '_oend': vars[old_pfx + '_oend'],
                 new_pfx + '_prev': vars[old_pfx + '_prev'],
                 new_pfx + '_next': vars[old_pfx + '_next']
                 })

def _paginate(prefix, n, offset, q):
  list = q.fetch(n + 1, offset - 1)
  have = len(list)

  if have == n + 1:
    list = list[0:-1]
    have = n
    next = offset + n
    if next >= 1000:
      next = None
  else:
    next = None

  if offset == 0:
    prev = None
  else:
    prev = offset - n
    if prev < 0:
      prev = 0

  if next:
    last = next - 1
  else:
    last = offset + have - 1

  for i in list:
    i.paginate_row_type = prefix

  return {prefix + '_list': list,
          prefix + '_opos': offset,
          prefix + '_oend': last,
          prefix + '_prev': prev,
          prefix + '_next': next}


def _user_mine(request, user, offset):
  r = _paginate('mine', 10, offset,
    models.gql(models.Change,
      'WHERE closed = FALSE AND owner = :1'
      ' ORDER BY modified DESC',
      user))
  _optimize_draft_counts(r['mine_list'])
  _prefetch_names(r['mine_list'])
  return r

def _user_review(request, user, offset):
  r = _paginate('review', 10, offset,
    models.gql(models.Change,
      'WHERE closed = FALSE AND reviewers = :1'
      ' ORDER BY modified DESC',
      user.email()))
  _optimize_draft_counts(r['review_list'])
  _prefetch_names(r['review_list'])
  return r

def _user_closed(request, user, offset):
  r =  _paginate('closed', 10, offset,
    models.gql(models.Change,
      'WHERE closed = TRUE AND owner = :1 AND modified > :2'
      ' ORDER BY modified DESC',
      user,
      datetime.datetime.now() - datetime.timedelta(days=7)
      ))
  _optimize_draft_counts(r['closed_list'])
  _prefetch_names(r['closed_list'])
  return r

def _show_user(request):
  user = request.user_to_show

  mine = _user_mine(request, user, 1)
  review = _user_review(request, user, 1)
  closed = _user_closed(request, user, 1)

  vars = {'email': user.email()}
  vars.update(mine)
  vars.update(review)
  vars.update(closed)

  return respond(request, 'user.html', vars)


def _get_emails(form, label):
  """Helper to return the list of reviewers, or None for error."""
  emails = []
  raw_emails = form.cleaned_data.get(label)
  if raw_emails:
    for email in raw_emails.split(','):
      email = email.strip().lower()
      if email and email not in emails:
        try:
          email = db.Email(email)
          if email.count('@') != 1:
            raise db.BadValueError('Invalid email address: %s' % email)
          head, tail = email.split('@')
          if '.' not in tail:
            raise db.BadValueError('Invalid email address: %s' % email)
        except db.BadValueError, err:
          form.errors[label] = [unicode(err)]
          continue
        emails.append(email)
  return emails

def _prepare_show_patchset(user, patchset):
  if user:
    drafts = list(models.gql(models.Comment,
             'WHERE ANCESTOR IS :1'
             ' AND draft = TRUE'
             ' AND author = :2',
             patchset, user))
  else:
    drafts = []

  max_rows = 100
  if len(patchset.filenames) < max_rows:
    files = models.gql(models.Patch,
                       'WHERE patchset = :1 ORDER BY filename',
                        patchset).fetch(max_rows)
    patchset.n_comments = 0
    patchset.n_drafts = len(drafts)
    patchset.patches = files

    if drafts:
      p_bykey = dict()
      for p in patchset.patches:
        p_bykey[p.key()] = p
        p._num_drafts = 0
        patchset.n_comments += p.num_comments

      for d in drafts:
        if d.parent_key() in p_bykey:
          p = p_bykey[d.parent_key()]
          p._num_drafts += 1
    else:
      for p in patchset.patches:
          p._num_drafts = 0
  else:
    patchset.freaking_huge = True
    patchset.patches = []


def _restrict_lgtm(lgtm, can_approve):
  if not can_approve:
    if lgtm == 'lgtm':
      return 'yes'
    elif lgtm == 'reject':
      return 'no'
  return lgtm
    

def _restrict_verified(verified, can_verify):
  if can_verify:
    return verified
  else:
    return False

def _map_status(rs, real_approvers, real_deniers, real_verifiers):
  email = rs.user.email()
  lgtm = _restrict_lgtm(rs.lgtm,
      (email in real_approvers) or (email in real_deniers))
  verified = _restrict_verified(rs.verified, email in real_verifiers)
  return {
      'user': rs.user,
      'lgtm': lgtm,
      'verified': verified,
    }

@change_required
def show(request, form=None):
  """/<change> - Show a change."""
  change = request.change

  messages = list(change.message_set.order('date'))
  patchsets = list(change.patchset_set.order('id'))
  if not patchsets:
    return HttpResponse('No patchset available.')

  last_patchset = patchsets[-1]
  _prepare_show_patchset(request.user, last_patchset)

  if last_patchset.patches:
    first_patch = last_patchset.patches[0]
  else:
    first_patch = None

  depends_on = [ r.patchset.change
                 for r in last_patchset.revision.get_ancestors()
                 if r.patchset ]
  needed_by  = [ r.patchset.change
                 for r in last_patchset.revision.get_children()
                 if r.patchset ]

  # approvals
  review_status = change.get_review_status()
  reviewer_status = models.Change.get_reviewer_status(review_status)
  ready_to_submit = project.ready_to_submit(
      change.dest_branch,
      change.owner,
      reviewer_status,
      last_patchset.filenames)

  # if the owner can lgtm or verify, show her too
  author_status = {
      'lgtm': 'lgtm' if ready_to_submit['owner_auto_lgtm'] else 'abstain',
      'verified': ready_to_submit['owner_auto_verify']
    }

  show_dependencies = len(needed_by) > 0
  for c in depends_on:
    if not c.closed:
      show_dependencies = True
  if change.closed:
    show_dependencies = False

  can_submit = ready_to_submit['can_submit']
  if not last_patchset.complete:
    can_submit = False

  real_approvers = ready_to_submit['real_approvers']
  real_deniers = ready_to_submit['real_deniers']
  real_verifiers = ready_to_submit['real_verifiers']

  real_review_status = [
      _map_status(rs, real_approvers, real_deniers, real_verifiers)
      for rs in review_status]

  # If the change isn't ready to submit, don't bother with this because
  # they can't submit it anyway.
  if can_submit:
    user_can_submit = models.AccountGroup.is_user_submitter(request.user)
  else:
    user_can_submit = False

  show_submit_button = ((not change.is_submitted)
                        and ready_to_submit
                        and user_can_submit)

  _prefetch_names([change])
  _prefetch_names(depends_on)
  _prefetch_names(needed_by)
  library.prefetch_names(map(lambda s: s.user, review_status))
  return respond(request, 'change.html', {
                  'change': change,
                  'ready_to_submit': can_submit,
                  'user_can_submit': user_can_submit,
                  'show_submit_button': show_submit_button,
                  'is_approved': ready_to_submit['approved'],
                  'is_rejected': ready_to_submit['denied'],
                  'is_verified': ready_to_submit['verified'],
                  'author_status': author_status,
                  'review_status': real_review_status,
                  'depends_on': depends_on,
                  'needed_by': needed_by,
                  'show_dependencies': show_dependencies,
                  'patchsets': patchsets,
                  'messages': messages,
                  'last_patchset': last_patchset,
                  'first_patch': first_patch,
                  'reply_url': '/%s/publish' % change.key().id(),
                  'merge_url': '/%s/merge/%s' % (change.key().id(),
                                                 last_patchset.key().id()),
                })


@patchset_required
def ajax_patchset(request):
  """/<change>/ajax_patchset/<ps> - Format one patchset."""
  change = request.change
  patchset = request.patchset

  _prepare_show_patchset(request.user, patchset)
  return respond(request, 'patchset.html',
                 {'change' : request.change,
                  'patchset' : request.patchset
                 })


def revision_redirect(request, hash):
  """/r/<hash> - Redirect to a Change for this git revision, if we can."""
  hash = hash.lower()
  if len(hash) < 40:
    q = models.gql(models.RevisionId,
                   "WHERE id > :1 AND id < :2",
                   hash, hash.ljust(40, 'z'))
  else:
    q = models.gql(models.RevisionId, "WHERE id=:1", hash)
  revs = q.fetch(2)
  count = len(revs)

  if count == 1:
    rev_id = revs[0]
    if rev_id.patchset:
      return HttpResponseRedirect('/%s' % rev_id.patchset.change.key().id())
    else:
      return respond(request, 'change_revision_unknown.html', { 'hash': hash })

  if count > 0:
    return http.HttpResponseServerError("error 500: multiple matches for hash")

  if len(hash) < 40:
    q = models.gql(git_models.ReceivedBundle,
                   "WHERE contained_objects > :1"
                   "  AND contained_objects < :2",
                   hash, hash.ljust(40, 'z'))
  else:
    q = models.gql(git_models.ReceivedBundle,
                   "WHERE contained_objects=:1",
                   hash)
  rb = q.get()
  if rb:
    return respond(request, 'change_revision_uploading.html',
                   { 'hash': hash })
  else:
    return respond(request, 'change_revision_unknown.html',
                   { 'hash': hash },
                   status = 404)


class EditChangeForm(BaseForm):
  _template = 'edit.html'

  reviewers = forms.CharField(required=False,
                              max_length=1000,
                              widget=forms.TextInput(attrs={'size': 60}))
  cc = forms.CharField(required=False,
                       max_length=1000,
                       label = 'CC',
                       widget=forms.TextInput(attrs={'size': 60}))
  closed = forms.BooleanField(required=False)

  @classmethod
  def _init(cls, change):
    return {'initial': {'reviewers': ', '.join(change.reviewers),
            'cc': ', '.join(change.cc),
            'closed': change.closed}}

  def _save(self, cd, change):
    change.closed = cd['closed']
    change.set_reviewers(_get_emails(self, 'reviewers'))
    change.cc = _get_emails(self, 'cc')
    change.put()

@change_owner_required
def edit(request):
  """/<change>/edit - Edit a change."""
  change = request.change
  id = change.key().id()
  def done():
    return HttpResponseRedirect('/%s' % id)
  return process_form(request, EditChangeForm, change, done,
                      {'change': change,
                       'del_url': '/%s/delete' % id})


@change_owner_required
@xsrf_required
def delete(request):
  """/<change>/delete - Delete a change.  There is no way back."""
  change = request.change

  for ps in models.PatchSet.gql('WHERE ANCESTOR IS :1', change):
    for rev in models.RevisionId.get_for_patchset(ps):
      rev.patchset = None
      rev.put()

  tbd = []
  for cls in [models.Patch,
              models.PatchSet,
              models.PatchSetFilenames,
              models.Comment,
              models.Message,
              models.ReviewStatus]:
    tbd += cls.gql('WHERE ANCESTOR IS :1', change).fetch(50)
    if len(tbd) > 100:
      db.delete(tbd)
      return respond(request, 'delete_loop.html',
                     {'change': change,
                      'del_url': '/%s/delete' % id})

  tbd += [change]
  db.delete(tbd)
  return HttpResponseRedirect('/mine')


@xsrf_required
@patchset_required
def merge(request):
  """/<change>/merge/<patchset> - Submit a change for merge."""
  change = request.change
  patchset = request.patchset
  patchset.patches = list(patchset.patch_set.order('filename'))

  if not models.AccountGroup.is_user_submitter(request.user):
    # The button shouldn't exist if they can't do it, if they somehow
    # managed to get here, just send them back to the change
    # (which ought to have the button gone this time).
    return HttpResponseRedirect('/%d' % change.key().id())

  # approvals
  reviewer_status = models.Change.get_reviewer_status(
      change.get_review_status())
  ready_to_submit = project.ready_to_submit(
      change.dest_branch,
      change.owner,
      reviewer_status,
      patchset.filenames)

  if not ready_to_submit['can_submit']:
    # Again, the button shouldn't have been there in this case.
    # Just send 'em back to the change page.
    return HttpResponseRedirect('/%d' % change.key().id())

  try:
    change.submit_merge(patchset)
    change.put()
  except models.InvalidSubmitMergeException, why:
    return HttpResponseForbidden(str(why))
  return HttpResponseRedirect('/mine')


@patch_required
def patch(request):
  """/<change>/patch/<patchset>/<patch> - View a raw patch."""
  return patch_helper(request)


def patch_helper(request, nav_type='patch'):
  """Returns a unified diff.

  Args:
    request: Django Request object.
    nav_type: the navigation used in the url (i.e. patch/diff/diff2).  Normally
      the user looks at either unified or side-by-side diffs at one time, going
      through all the files in the same mode.  However, if side-by-side is not
      available for some files, we temporarly switch them to unified view, then
      switch them back when we can.  This way they don't miss any files.

  Returns:
    Whatever respond() returns.
  """
  _add_next_prev(request.patchset, request.patch)
  request.patch.nav_type = nav_type
  parsed_lines = patching.ParsePatchToLines(request.patch.patch_lines)
  if parsed_lines is None:
    return HttpResponseNotFound('Can\'t parse the patch')
  rows = engine.RenderUnifiedTableRows(request, parsed_lines)
  return respond(request, 'patch.html',
                 {'patch': request.patch,
                  'patchset': request.patchset,
                  'rows': rows,
                  'change': request.change})


@patch_required
def download_patch(request):
  """/download/change<change>_<patchset>_<patch>.diff - Download patch."""
  return HttpResponse(request.patch.patch_text, content_type='text/plain')


def _get_context_for_user(request):
  """Returns the context setting for a user.

  The value is validated against models.CONTEXT_CHOICES.
  If an invalid value is found, the value is overwritten with
  models.DEFAULT_CONTEXT.
  """
  if request.user:
    account = models.Account.current_user_account
    default_context = account.default_context
  else:
    default_context = models.DEFAULT_CONTEXT
  try:
    context = int(request.GET.get("context", default_context))
  except ValueError:
    context = default_context
  if context not in models.CONTEXT_CHOICES:
    context = models.DEFAULT_CONTEXT
  return context


@patch_required
def diff(request):
  """/<change>/diff/<patchset>/<patch> - View a patch as a side-by-side diff"""
  patchset = request.patchset
  patch = request.patch

  context = _get_context_for_user(request)
  rows = _get_diff_table_rows(request, patch, context)
  if isinstance(rows, HttpResponseNotFound):
    return rows

  _add_next_prev(patchset, patch)
  return respond(request, 'diff.html',
                 {'change': request.change, 'patchset': patchset,
                  'patch': patch, 'rows': rows,
                  'context': context, 'context_values': models.CONTEXT_CHOICES})


def _get_diff_table_rows(request, patch, context):
  """Helper function that returns rendered rows for a patch"""
  chunks = patching.ParsePatchToChunks(patch.patch_lines,
                                       patch.filename)
  if chunks is None:
    return HttpResponseNotFound('Can\'t parse the patch')

  return list(engine.RenderDiffTableRows(request, patch.old_lines,
                                         chunks, patch,
                                         context=context))


@patch_required
def diff_skipped_lines(request, id_before, id_after, where):
  """/<change>/diff/<patchset>/<patch> - Returns a fragment of skipped lines"""
  patchset = request.patchset
  patch = request.patch

  # TODO: allow context = None?
  rows = _get_diff_table_rows(request, patch, 10000)
  if isinstance(rows, HttpResponseNotFound):
    return rows
  return _get_skipped_lines_response(rows, id_before, id_after, where)


def _get_skipped_lines_response(rows, id_before, id_after, where):
  """Helper function that creates a Response object for skipped lines"""
  response_rows = []
  id_before = int(id_before)
  id_after = int(id_after)

  if where == "b":
    rows.reverse()

  for row in rows:
    m = re.match('^<tr( name="hook")? id="pair-(?P<rowcount>\d+)">', row)
    if m:
      curr_id = int(m.groupdict().get("rowcount"))
      if curr_id < id_before or curr_id > id_after:
        continue
      if where  == "b" and curr_id <= id_after:
        response_rows.append(row)
      elif where == "t" and curr_id >= id_before:
        response_rows.append(row)
      if len(response_rows) >= 10:
        break

  # Create a usable structure for the JS part
  response = []
  dom = ElementTree.parse(StringIO('<div>%s</div>' % "".join(response_rows)))
  for node in dom.getroot().getchildren():
    content = "\n".join([ElementTree.tostring(x) for x in node.getchildren()])
    response.append([node.items(), content])
  return HttpResponse(simplejson.dumps(response))


def _get_diff2_data(request, ps_left_id, ps_right_id, patch_id, context):
  """Helper function that returns objects for diff2 views"""
  ps_left = models.PatchSet.get_by_id(int(ps_left_id), parent=request.change)
  if ps_left is None:
    return HttpResponseNotFound('No patch set exists with that id (%s)' %
                                ps_left_id)
  ps_left.change = request.change
  ps_right = models.PatchSet.get_by_id(int(ps_right_id), parent=request.change)
  if ps_right is None:
    return HttpResponseNotFound('No patch set exists with that id (%s)' %
                                ps_right_id)
  ps_right.change = request.change
  patch_right = models.Patch.get_patch(ps_right, patch_id)
  if patch_right is None:
    return HttpResponseNotFound('No patch exists with that id (%s/%s)' %
                                (ps_right_id, patch_id))
  patch_right.patchset = ps_right
  # Now find the corresponding patch in ps_left
  patch_left = models.Patch.gql('WHERE patchset = :1 AND filename = :2',
                                ps_left, patch_right.filename).get()
  if patch_left is None:
    return HttpResponseNotFound(
        "Patch set %s doesn't have a patch with filename %s" %
        (ps_left_id, patch_right.filename))

  rows = engine.RenderDiff2TableRows(request,
                                     patch_left.new_lines, patch_left,
                                     patch_right.new_lines, patch_right,
                                     context=context)
  rows = list(rows)
  if rows and rows[-1] is None:
    del rows[-1]

  return dict(patch_left=patch_left, ps_left=ps_left,
              patch_right=patch_right, ps_right=ps_right,
              rows=rows)


@change_required
def diff2(request, ps_left_id, ps_right_id, patch_id):
  """/<change>/diff2/... - View the delta between two different patch sets."""
  context = _get_context_for_user(request)
  data = _get_diff2_data(request, ps_left_id, ps_right_id, patch_id, context)
  if isinstance(data, HttpResponseNotFound):
    return data

  _add_next_prev(data["ps_right"], data["patch_right"])
  return respond(request, 'diff2.html',
                 {'change': request.change,
                  'ps_left': data["ps_left"],
                  'patch_left': data["patch_left"],
                  'ps_right': data["ps_right"],
                  'patch_right': data["patch_right"],
                  'rows': data["rows"],
                  'patch_id': patch_id,
                  'context': context,
                  'context_values': models.CONTEXT_CHOICES,
                  })


@change_required
def diff2_skipped_lines(request, ps_left_id, ps_right_id, patch_id,
                        id_before, id_after, where):
  """/<change>/diff2/... - Returns a fragment of skipped lines"""
  data = _get_diff2_data(request, ps_left_id, ps_right_id, patch_id, 10000)
  if isinstance(data, HttpResponseNotFound):
    return data
  return _get_skipped_lines_response(data["rows"], id_before, id_after, where)


def _add_next_prev(patchset, patch):
  """Helper to add .next and .prev attributes to a patch object."""
  patch.prev = patch.next = None
  patches = list(models.Patch.gql("WHERE patchset = :1 ORDER BY filename",
                                  patchset))
  patchset.patches = patches  # Required to render the jump to select.
  last = None
  for p in patches:
    if last is not None:
      if p.filename == patch.filename:
        patch.prev = last
      elif last.filename == patch.filename:
        patch.next = p
        break
    last = p


def inline_draft(request):
  """/inline_draft - Ajax handler to submit an in-line draft comment.

  This wraps _inline_draft(); all exceptions are logged and cause an
  abbreviated response indicating something went wrong.
  """
  if request.method != 'POST':
    return HttpResponse("POST request required.", status=405)
  try:
    return _inline_draft(request)
  except Exception, err:
    s = ''
    for k,v in request.POST.iteritems():
      s += '\n%s=%s' % (k, v)
    logging.exception('Exception in inline_draft processing:%s' % s)
    return HttpResponse('<font color="red">'
                        'Please report error "%s".'
                        '</font>'
                        % err.__class__.__name__)


def _inline_draft(request):
  """Helper to submit an in-line draft comment.
  """
  # Don't use @login_required; JS doesn't understand redirects.
  if not request.user:
    return HttpResponse('<font color="red">Not logged in</font>')

  if not is_xsrf_ok(request):
    return HttpResponse('<font color="red">'
                        'Stale xsrf signature.<br />'
                        'Please reload the page and try again.'
                        '</font>')

  snapshot = request.POST.get('snapshot')
  assert snapshot in ('old', 'new'), repr(snapshot)
  left = (snapshot == 'old')
  side = request.POST.get('side')
  assert side in ('a', 'b'), repr(side)  # Display left (a) or right (b)
  change_id = int(request.POST['change'])
  change = models.Change.get_by_id(change_id)
  assert change  # XXX
  patchset_id = request.POST.get('patchset') or request.POST[side == 'a' and 'ps_left' or 'ps_right']
  patchset = models.PatchSet.get_by_id(int(patchset_id), parent=change)
  assert patchset  # XXX
  patch_id = request.POST.get('patch') or request.POST[side == 'a' and 'patch_left' or 'patch_right']
  patch = models.Patch.get_patch(patchset, patch_id)
  assert patch  # XXX
  text = request.POST.get('text')
  lineno = int(request.POST['lineno'])
  message_id = request.POST.get('message_id')
  comment = None
  if message_id:
    comment = models.Comment.get_by_key_name(message_id, parent=patch)
    if comment is None or not comment.draft or comment.author != request.user:
      comment = None
      message_id = None
  if not message_id:
    # Prefix with 'z' to avoid key names starting with digits.
    message_id = 'z' + binascii.hexlify(_random_bytes(16))

  if not text.rstrip():
    if comment is not None:
      assert comment.draft and comment.author == request.user
      comment.delete()  # Deletion
      comment = None
      # Re-query the comment count.
      models.Account.current_user_account.update_drafts(change)
  else:
    if comment is None:
      comment = models.Comment(
                  patch=patch,
                  key_name=message_id,
                  parent=patch)
    comment.lineno = lineno
    comment.left = left
    comment.author = request.user
    comment.text = db.Text(text)
    comment.message_id = message_id
    comment.put()
    # The actual count doesn't matter, just that there's at least one.
    models.Account.current_user_account.update_drafts(change, 1)

  query = models.Comment.gql(
      'WHERE patch = :patch AND lineno = :lineno AND left = :left '
      'ORDER BY date',
      patch=patch, lineno=lineno, left=left)
  comments = list(c for c in query if not c.draft or c.author == request.user)
  if comment is not None and comment.author is None:
    # Show anonymous draft even though we don't save it
    comments.append(comment)
  if not comments:
    return HttpResponse(' ')
  for c in comments:
    c.complete(patch)
  return render_to_response('inline_comment.html',
                            {'inline_draft_url': '/inline_draft',
                             'user': request.user,
                             'patch': patch,
                             'patchset': patchset,
                             'change': change,
                             'comments': comments,
                             'lineno': lineno,
                             'snapshot': snapshot,
                             'side': side})


class PublishCommentsForm(BaseForm):
  _template = 'publish.html'

  reviewers = forms.CharField(required=False,
                              max_length=1000,
                              widget=forms.TextInput(attrs={'size': 60}))
  cc = forms.CharField(required=False,
                       max_length=1000,
                       label = 'CC',
                       widget=forms.TextInput(attrs={'size': 60}))
  send_mail = forms.BooleanField(required=False)
  message = forms.CharField(required=False,
                            max_length=10000,
                            widget=forms.Textarea(attrs={'cols': 60}))

  lgtm = forms.CharField(label='Code review')
  verified = forms.BooleanField(required=False,
                                label='Verified')



  def __init__(self, *args, **kwargs):
    is_initial = kwargs.pop('is_initial', False)
    self.user_can_approve = kwargs.pop('user_can_approve', False)
    self.user_can_verify = kwargs.pop('user_can_verify', False)
    self.user_is_owner = kwargs.pop('user_is_owner', False)

    BaseForm.__init__(self, *args, **kwargs)

    if is_initial:
      # only show the available lgtm options
      lgtm_field = self.fields.get("lgtm")
      if self.user_can_approve and not self.user_is_owner:
        lgtm_field.widget = forms.RadioSelect(choices=models.LGTM_CHOICES)
      else:
        lgtm_field.widget = forms.RadioSelect(
               choices=models.LIMITED_LGTM_CHOICES)
      
      # only show verified if the user can do it
      if not self.user_can_verify or self.user_is_owner:
        del self.fields['verified']

  @classmethod
  def _init(cls, state):
    request, change = state
    user = request.user

    reviewers = list(change.reviewers)
    cc = list(change.cc)

    if user != change.owner and user.email() not in reviewers:
      reviewers.append(user.email())
      if user.email() in cc:
        cc.remove(user.email())

    (user_can_approve,user_can_verify) = project.user_can_approve(
          request.user, change)

    # Pick the proper review / verify status
    review = change.get_review_status(user)
    if review:
      lgtm = _restrict_lgtm(review.lgtm, user_can_approve)
      verified = review.verified
    else:
      lgtm = 'abstain'
      verified = False

    return {'initial': {
              'reviewers': ', '.join(reviewers),
              'cc': ', '.join(cc),
              'send_mail': True,
              'lgtm': lgtm,
              'verified': verified
              },
            'user_can_approve': user_can_approve,
            'user_can_verify': user_can_verify,
            'user_is_owner': user == change.owner,
            'is_initial': True,
          }

  def _save(self, cd, state):
    request, change = state
    user = request.user

    tbd, comments = _get_draft_comments(request, change)
    reviewers = _get_emails(self, 'reviewers')
    cc = _get_emails(self, 'cc')
    (self.user_can_approve,self.user_can_verify) = project.user_can_approve(
          request.user, change)
    lgtm = _restrict_lgtm(cd.get('lgtm', ''), self.user_can_approve)
    verified = _restrict_verified(cd.get('verified', False),
          self.user_can_verify)

    if user != change.owner:
      # Owners shouldn't have their own review status as it
      # is implied that 'lgtm' and verified by them.
      #
      review_status = _update_review_status(change,
                                            user,
                                            lgtm,
                                            verified)
      tbd.append(review_status)

    change.set_reviewers(reviewers)
    change.cc = cc
    change.update_comment_count(len(comments))

    msg = _make_comment_message(request, change, lgtm, verified,
                        cd['message'],
                        comments,
                        cd['send_mail'])
    tbd.append(msg)
    tbd.append(change)

    while tbd:
      db.put(tbd[:50])
      tbd = tbd[50:]
    models.Account.current_user_account.update_drafts(change, 0)

@change_required
@login_required
def publish(request):
  """ /<change>/publish - Publish draft comments and send mail."""
  change = request.change

  tbd, comments = _get_draft_comments(request, change, True)
  preview = _get_draft_details(request, comments)

  def done():
    return HttpResponseRedirect('/%s' % change.key().id())
  return process_form(request, PublishCommentsForm, (request, change), done,
                      {'change': change,
                       'preview' : preview})


def _update_review_status(change, user, lgtm, verified):
  """Creates / updates the ReviewStatus for a user, returns that object."""
  review = change.set_review_status(user)
  review.lgtm = lgtm
  review.verified = verified
  return review



def _encode_safely(s):
  """Helper to turn a unicode string into 8-bit bytes."""
  if isinstance(s, unicode):
    s = s.encode('utf-8')
  return s


def _get_draft_comments(request, change, preview=False):
  """Helper to return objects to put() and a list of draft comments.

  If preview is True, the list of objects to put() is empty to avoid changes
  to the datastore.

  Args:
    request: Django Request object.
    change: Change instance.
    preview: Preview flag (default: False).

  Returns:
    2-tuple (put_objects, comments).
  """
  comments = []
  tbd = []
  dps = dict()

  # XXX Should request all drafts for this change once, now we can.
  for patchset in change.patchset_set.order('id'):
    ps_comments = list(models.Comment.gql(
        'WHERE ANCESTOR IS :1 AND author = :2 AND draft = TRUE',
        patchset, request.user))
    if ps_comments:
      patches = dict((p.key(), p) for p in patchset.patch_set)
      for p in patches.itervalues():
        p.patchset = patchset
      for c in ps_comments:
        c.draft = False
        # XXX Using internal knowledge about db package: the key for
        # reference property foo is stored as _foo.
        pkey = getattr(c, '_patch', None)
        if pkey in patches:
          patch = patches[pkey]
          c.patch = patch
        if pkey not in dps:
          dps[pkey] = c.patch
        c.patch.update_comment_count(1)
      if not preview:
        tbd += ps_comments
      ps_comments.sort(key=lambda c: (c.patch.filename, not c.left,
                                      c.lineno, c.date))
      comments += ps_comments
  if not preview:
    tbd += dps.values()
  return tbd, comments

FILE_LINE = '======================================================================'
COMMENT_LINE = '------------------------------'

def _get_draft_details(request, comments):
  """Helper to display comments with context in the email message."""
  last_key = None
  output = []
  linecache = {}  # Maps (c.patch.filename, c.left) to list of lines
  for c in comments:
    if (c.patch.filename, c.left) != last_key:
      if not last_key is None:
        output.append('%s\n' % FILE_LINE)
      url = request.build_absolute_uri('/%d/diff/%d/%s' %
                                       (request.change.key().id(),
                                        c.patch.patchset.key().id(),
                                        c.patch.id))
      output.append('\n%s\n%s\nFile %s:' % (FILE_LINE, url, c.patch.filename))
      last_key = (c.patch.filename, c.left)
      patch = c.patch
      if c.left:
        linecache[last_key] = patch.old_lines
      else:
        linecache[last_key] = patch.new_lines
    file_lines = linecache.get(last_key, ())
    context = ''
    if 1 <= c.lineno <= len(file_lines):
      context = file_lines[c.lineno - 1].strip()
    url = request.build_absolute_uri('/%d/diff/%d/%s#%scode%d' %
                                     (request.change.key().id(),
                                      c.patch.patchset.key().id(),
                                      c.patch.id,
                                      c.left and "old" or "new",
                                      c.lineno))
    output.append('%s\nLine %d: %s\n%s'  % (COMMENT_LINE, c.lineno,
                                                context, c.text.rstrip()))
  if not last_key is None:
    output.append('%s\n' % FILE_LINE)
  return '\n'.join(output)

def _make_comment_message(request, change, lgtm, verified, message,
                  comments=None, send_mail=False):
  """Helper to create a Message instance and optionally send an email."""
  # Decide who should receive mail
  my_email = db.Email(request.user.email())
  to = [db.Email(change.owner.email())] + change.reviewers
  cc = change.cc[:]
  reply_to = to + cc
  if my_email in to and len(to) > 1:  # send_mail() wants a non-empty to list
    to.remove(my_email)
  if my_email in cc:
    cc.remove(my_email)
  subject = email.make_change_subject(change)
  if comments:
    details = _get_draft_details(request, comments)
  else:
    details = ''
  prefix = ''
  if lgtm:
    prefix = prefix + [y for (x,y) in models.LGTM_CHOICES
                       if x == lgtm][0] + '\n'
  if verified:
    prefix = prefix + 'Verified.\n'
  if prefix:
    prefix = prefix + '\n'
  message = message.replace('\r\n', '\n')
  message = prefix + message
  text = ((message.strip() + '\n\n' + details.strip())).strip()
  msg = models.Message(change=change,
                       subject=subject,
                       sender=my_email,
                       recipients=reply_to,
                       text=db.Text(text),
                       parent=change)

  if send_mail:
    to_users = set([change.owner] + change.reviewers + cc)
    template_args = {
        'message': message,
        'details': details,
      }
    email.send_change_message(request, change,
                              'mails/comment.txt', template_args)

  return msg


@xsrf_required
@posted_change_required
def star(request):
  account = models.Account.current_user_account
  if account.stars is None:
    account.stars = []
  id = request.change.key().id()
  if id not in account.stars:
    account.stars.append(id)
    account.put()
  return respond(request, 'change_star.html', {'change': request.change})


@xsrf_required
@posted_change_required
def unstar(request):
  account = models.Account.current_user_account
  if account.stars is None:
    account.stars = []
  id = request.change.key().id()
  if id in account.stars:
    account.stars[:] = [i for i in account.stars if i != id]
    account.put()
  return respond(request, 'change_star.html', {'change': request.change})


@gae_admin_required
def download_bundle(request, bundle_id, segment_id):
  """/download/bundle(\d+)_(\d+) - get a bundle segment"""
  rb = git_models.ReceivedBundle.get_by_id(int(bundle_id))
  if not rb:
    return HttpResponseNotFound('No bundle exists with that id (%s)' % bundle_id)
  seg = rb.get_segment(int(segment_id))
  if not seg:
    return HttpResponseNotFound('No segment %s in bundle %s' % (segment_id,bundle_id))
  return HttpResponse(seg.bundle_data,
                      content_type='application/x-git-bundle-segment')


### Administration ###

@project_owner_or_admin_required
def admin(request):
  """/admin - user & other settings"""
  return respond(request, 'admin.html', {})

@gae_admin_required
def admin_settings(request):
  settings = models.Settings.get_settings()
  return respond(request, 'admin_settings.html', {
            'settings': settings,
            'from_email_test_xsrf': xsrf_for('/admin/settings/from_email_test')
          })

class AdminSettingsAnalyticsForm(BaseForm):
  _template = 'admin_settings_analytics.html'

  analytics = forms.CharField(required=False, max_length=20,
                              widget=forms.TextInput(attrs={'size': 20}))

  @classmethod
  def _init(cls, state):
    settings = models.Settings.get_settings()
    return {'initial': {
                'analytics': settings.analytics,
              }
            }

  def _save(self, cd, change):
    settings = models.Settings.get_settings()
    settings.analytics = cd['analytics']
    settings.put()

@gae_admin_required
def admin_settings_analytics(request):
  def done():
    return HttpResponseRedirect('/admin/settings')
  return process_form(request, AdminSettingsAnalyticsForm, None, done)

class AdminSettingsFromEmailForm(BaseForm):
  _template = 'admin_settings_from_email.html'

  from_email = forms.CharField(required=False,
                              max_length=60,
                              widget=forms.TextInput(attrs={'size': 60}))

  @classmethod
  def _init(cls, state):
    settings = models.Settings.get_settings()
    return {'initial': {
                'from_email': settings.from_email,
              }
            }

  def _save(self, cd, change):
    settings = models.Settings.get_settings()
    settings.from_email = cd['from_email']
    settings.put()

@gae_admin_required
def admin_settings_from_email(request):
  def done():
    return HttpResponseRedirect('/admin/settings')
  return process_form(request, AdminSettingsFromEmailForm, None, done)

@gae_admin_required
def admin_settings_from_email_test(request):
  if request.method == 'POST':
    if is_xsrf_ok(request, xsrf=request.POST.get('xsrf')):
      address = email.get_default_sender()
      try:
        mail.check_email_valid(address, 'blah')
        email.send(None, [models.Account.current_user_account], 'test',
                              'mails/from_email_test.txt', None)
        status = 'email sent'
      except mail.InvalidEmailError:
        status = 'invalid email address'
      return respond(request, 'admin_settings_from_email_test.html', {
                  'status': status,
                  'address': address
                })
  return HttpResponse('<font color="red">Ich don\'t think so!</font>')



### User Profiles ###

def validate_real_name(real_name):
  """Returns None if real_name is fine and an error message otherwise."""
  if not real_name:
    return 'Name cannot be empty.'
  elif real_name == 'me':
    return 'Of course, you are what you are.  But \'me\' is for everyone.'
  else:
    return None


@user_key_required
def user_popup(request):
  """/user_popup - Pop up to show the user info."""
  try:
    user = request.user_to_show
    def gen():
      account = models.Account.get_account_for_user(user)
      return render_to_response('user_popup.html', {'account': account})
    return MemCacheKey('user_popup:' + user.email(), 300).get(gen)
  except Exception, err:
    logging.exception('Exception in user_popup processing:')
    return HttpResponse(
      '<font color="red">Error: %s; please report!</font>'
      % err.__class__.__name__)


class AdminDataStoreDeleteForm(BaseForm):
  _template = 'admin_datastore_delete.html'

  really = forms.CharField(required=True)

  def _save(self, cd, request):
    if cd['really'] != 'DELETE EVERYTHING':
      return self

    max_cnt = 50
    rm = []
    specials = []
    for cls in [models.ApprovalRight,
                models.Project,
                models.Branch,
                models.RevisionId,
                models.BuildAttempt,
                models.Change,
                models.PatchSetFilenames,
                models.PatchSet,
                models.Message,
                models.DeltaContent,
                models.Patch,
                models.Comment,
                models.Bucket,
                models.ReviewStatus,
                models.Account,
                models.AccountGroup,
                git_models.ReceivedBundleSegment,
                git_models.ReceivedBundle,
               ]:
      all = cls.all().fetch(max_cnt)
      if cls == models.Account:
        for a in all:
          if a.key() == request.account.key():
            specials.append(a)
          else:
            rm.append(a)
      elif cls == models.AccountGroup:
        for a in all:
          if a.is_auto_group:
            specials.append(a)
          else:
            rm.append(a)
      else:
        rm.extend(all)
      if len(rm) >= max_cnt:
        break

    if rm:
      # Delete this block of data and continue via
      # a JavaScript reload in the browser.
      #
      db.delete(rm)
      return self

    # We are done with the bulk of the content, but we need
    # to clean up a few special objects.
    #
    library._user_cache.clear()
    models.Settings._Key.clear()

    specials.extend(models.Settings.all().fetch(100))
    db.delete(specials)
    return None

@gae_admin_required
def admin_datastore_delete(request):
  def done():
    return HttpResponseRedirect('/')
  return process_form(request, AdminDataStoreDeleteForm, request, done)


class AdminDataStoreUpgradeForm(BaseForm):
  _template = 'admin_datastore_upgrade.html'

  really = forms.CharField(required=True)

  def _save(self, cd, request):
    if cd['really'] != 'UPGRADE':
      return self
    return None

@gae_admin_required
def admin_datastore_upgrade(request):
  def done():
    return HttpResponseRedirect('/')
  return process_form(request, AdminDataStoreUpgradeForm, request, done)
