# Copyright 2016 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 or at
# https://developers.google.com/open-source/licenses/bsd

"""Servlet to show the original email that caused an issue comment.

The text of the body the email is shown in an HTML page with <pre>.
All the text is automatically escaped by EZT to make it safe to
include in an HTML page.
"""
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import

import logging
import ezt

from businesslogic import work_env
from framework import flaskservlet
from framework import filecontent
from framework import permissions
from framework import servlet
from services import issue_svc


class IssueOriginal(servlet.Servlet):
  """IssueOriginal shows an inbound email that caused an issue comment."""

  _PAGE_TEMPLATE = 'tracker/issue-original-page.ezt'

  def AssertBasePermission(self, mr):
    """Make sure that the logged in user has permission to view this page."""
    super(IssueOriginal, self).AssertBasePermission(mr)
    issue, comment = self._GetIssueAndComment(mr)

    # TODO(jrobbins): take granted perms into account here.
    if issue and not permissions.CanViewIssue(
        mr.auth.effective_ids, mr.perms, mr.project, issue,
        allow_viewing_deleted=True):
      raise permissions.PermissionException(
          'User is not allowed to view this issue')

    can_view_inbound_message = self.CheckPerm(
        mr, permissions.VIEW_INBOUND_MESSAGES, art=issue)
    issue_perms = permissions.UpdateIssuePermissions(
        mr.perms, mr.project, issue, mr.auth.effective_ids)
    commenter = self.services.user.GetUser(mr.cnxn, comment.user_id)
    can_view_comment = permissions.CanViewComment(
        comment, commenter, mr.auth.user_id, issue_perms)
    if not can_view_inbound_message or not can_view_comment:
      raise permissions.PermissionException(
          'Only project members may view original email text')

  def GatherPageData(self, mr):
    """Build up a dictionary of data values to use when rendering the page.

    Args:
      mr: commonly used info parsed from the request.

    Returns:
      Dict of values used by EZT for rendering the page.
    """
    issue, comment = self._GetIssueAndComment(mr)
    message_body_unicode, is_binary, _is_long = (
        filecontent.DecodeFileContents(comment.inbound_message))

    # Take out the iso8859-1 non-breaking-space characters that gmail
    # inserts between consecutive spaces when quoting text in a reply.
    # You can see this in gmail by sending a plain text reply to a
    # message that had multiple spaces on some line, then use the
    # "Show original" menu item to view your reply, you will see "=A0".
    #message_body_unicode = message_body_unicode.replace(u'\xa0', u' ')

    page_data = {
        'local_id': issue.local_id,
        'seq': comment.sequence,
        'is_binary': ezt.boolean(is_binary),
        'message_body': message_body_unicode,
        }

    return page_data

  def _GetIssueAndComment(self, mr):
    """Wait on retriving the specified issue and issue comment."""
    if mr.seq is None:
      self.abort(404, 'comment not specified')

    with work_env.WorkEnv(mr, self.services) as we:
      issue = self.services.issue.GetIssueByLocalID(
          mr.cnxn, mr.project_id, mr.local_id)
      comments = we.ListIssueComments(issue)

    try:
      comment = comments[mr.seq]
    except IndexError:
      self.abort(404, 'comment not found')

    return issue, comment

  # def GetIssueOriginal(self, **kwargs):
  #   return self.handler(**kwargs)
