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

"""Simple Request handler using Jinja2 templates."""

import logging
import os

import jinja2
import webapp2

from google.appengine.api import users

from dashboard import utils
from dashboard import xsrf

JINJA2_ENVIRONMENT = jinja2.Environment(
    loader=jinja2.FileSystemLoader(
        [os.path.join(os.path.dirname(__file__), 'templates')]),
    # Security team suggests that autoescaping be enabled.
    autoescape=True,
    extensions=['jinja2.ext.autoescape'])


class RequestHandler(webapp2.RequestHandler):
  """Base class for requests. Does common template and error handling tasks."""

  def RenderHtml(self, template_file, template_values, status=200):
    """Renders HTML given template and values.

    Args:
      template_file: string. File name under templates directory.
      template_values: dict. Mapping of template variables to corresponding.
          values.
      status: int. HTTP status code.
    """
    self.response.set_status(status)
    template = JINJA2_ENVIRONMENT.get_template(template_file)
    self.GetDynamicVariables(template_values)
    self.response.out.write(template.render(template_values))

  def RenderStaticHtml(self, filename):
    filename = os.path.join(os.path.dirname(__file__), 'static', filename)
    contents = open(filename, 'r')
    self.response.out.write(contents.read())
    contents.close()

  def GetDynamicVariables(self, template_values, request_path=None):
    """Gets the values that vary for every page.

    Args:
      template_values: dict of name/value pairs.
      request_path: path for login urls, None if using the current path.
    """
    user_info = ''
    xsrf_token = ''
    user = users.get_current_user()
    display_username = 'Sign in'
    title = 'Sign in to an account'
    is_admin = False
    if user:
      display_username = user.email()
      title = 'Switch user'
      xsrf_token = xsrf.GenerateToken(user)
      is_admin = users.is_current_user_admin()
    try:
      login_url = users.create_login_url(request_path or self.request.path_qs)
    except users.RedirectTooLongError:
      # On the bug filing pages, the full login URL can be too long. Drop
      # the correct redirect URL, since the user should already be logged in at
      # this point anyway.
      login_url = users.create_login_url('/')
    user_info = '<a href="%s" title="%s">%s</a>' % (
        login_url, title, display_username)
    template_values['login_url'] = login_url
    template_values['display_username'] = display_username
    template_values['user_info'] = user_info
    template_values['is_admin'] = is_admin
    template_values['is_internal_user'] = utils.IsInternalUser()
    template_values['xsrf_token'] = xsrf_token
    template_values['xsrf_input'] = (
        '<input type="hidden" name="xsrf_token" value="%s">' % xsrf_token)
    template_values['login_url'] = login_url
    return template_values

  def ReportError(self, error_message, status=500):
    """Reports the given error to the client and logs the error.

    Args:
      error_message: The message to log and send to the client.
      status: The HTTP response code to use.
    """
    logging.error(error_message)
    self.response.set_status(status)
    self.response.out.write('%s\nrequest_id:%s\n' %
                            (error_message, utils.GetRequestId()))

  def ReportWarning(self, warning_message, status=200):
    """Reports a warning to the client and logs the warning.

    Args:
      warning_message: The warning message to log (as an error).
      status: The http response code to use.
    """
    logging.warning(warning_message)
    self.response.set_status(status)
    self.response.out.write('%s\nrequest_id:%s\n' %
                            (warning_message, utils.GetRequestId()))


class InvalidInputError(Exception):
  """An error class for invalid user input query parameter values."""
  pass
