#!/usr/bin/env python
#
# Copyright 2007 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.
#
"""Dispatcher for dynamic image serving requests.

Classes:

  CreateBlobImageDispatcher:
    Creates a dispatcher that will handle an image serving request. It will
    fetch an image from blobstore and dynamically resize it.
"""



import logging
import re
import urlparse

from google.appengine.api import datastore
from google.appengine.api import datastore_errors
from google.appengine.api.images import images_service_pb

BLOBIMAGE_URL_PATTERN = '/_ah/img(?:/.*)?'

BLOBIMAGE_RESPONSE_TEMPLATE = (
    'Status: %(status)s\r\nContent-Type: %(content_type)s\r\n'
    'Cache-Control: public, max-age=600, no-transform'
    '\r\n\r\n%(data)s')


BLOB_SERVING_URL_KIND = '__BlobServingUrl__'


DEFAULT_SERVING_SIZE = 512

def CreateBlobImageDispatcher(images_stub):
  """Function to create a dynamic image serving stub.

  Args:
    images_stub: an images_stub to perform the image resizing on blobs.


  Returns:
    New dispatcher capable of dynamic image serving requests.
  """



  from google.appengine.tools import old_dev_appserver

  class BlobImageDispatcher(old_dev_appserver.URLDispatcher):
    """Dispatcher that handles image serving requests."""

    _size_limit = 1600
    _mime_type_map = {images_service_pb.OutputSettings.JPEG: 'image/jpeg',
                      images_service_pb.OutputSettings.PNG: 'image/png',
                      images_service_pb.OutputSettings.WEBP: 'image/webp'}

    def __init__(self, images_stub):
      """Constructor.

      Args:
        images_stub: an images_stub to perform the image resizing on blobs.
      """
      self._images_stub = images_stub

    def _TransformImage(self, blob_key, options):
      """Construct and execute transform request to the images stub.

      Args:
        blob_key: blob_key to the image to transform.
        options: resize and crop option string to apply to the image.

      Returns:
        The tranformed (if necessary) image bytes.
      """
      resize, crop = self._ParseOptions(options)

      image_data = images_service_pb.ImageData()
      image_data.set_blob_key(blob_key)
      image = self._images_stub._OpenImageData(image_data)
      original_mime_type = image.format
      width, height = image.size


      if crop:
        crop_xform = None
        if width > height:

          crop_xform = images_service_pb.Transform()
          delta = (width - height) / (width * 2.0)
          crop_xform.set_crop_left_x(delta)
          crop_xform.set_crop_right_x(1.0 - delta)
        elif width < height:

          crop_xform = images_service_pb.Transform()
          delta = (height - width) / (height * 2.0)
          top_delta = max(0.0, delta - 0.25)
          bottom_delta = 1.0 - (2.0 * delta) + top_delta
          crop_xform.set_crop_top_y(top_delta)
          crop_xform.set_crop_bottom_y(bottom_delta)
        if crop_xform:
          image = self._images_stub._Crop(image, crop_xform)


      if resize is None:
        if width > DEFAULT_SERVING_SIZE or height > DEFAULT_SERVING_SIZE:
          resize = DEFAULT_SERVING_SIZE


      if resize:

        resize_xform = images_service_pb.Transform()
        resize_xform.set_width(resize)
        resize_xform.set_height(resize)
        image = self._images_stub._Resize(image, resize_xform)

      output_settings = images_service_pb.OutputSettings()


      output_mime_type = images_service_pb.OutputSettings.JPEG
      if original_mime_type in ['PNG', 'GIF']:
        output_mime_type = images_service_pb.OutputSettings.PNG
      output_settings.set_mime_type(output_mime_type)
      return (self._images_stub._EncodeImage(image, output_settings),
              self._mime_type_map[output_mime_type])

    def _ParseOptions(self, options):
      """Currently only support resize and crop options.

      Args:
        options: the url resize and crop option string.

      Returns:
        (resize, crop) options parsed from the string.
      """
      match = re.search('^s(\\d+)(-c)?', options)
      resize = None
      crop = False
      if match:
        if match.group(1):
          resize = int(match.group(1))
        if match.group(2):
          crop = True


      if resize and (resize > BlobImageDispatcher._size_limit or
                     resize < 0):
        raise ValueError, 'Invalid resize'
      return (resize, crop)

    def _ParseUrl(self, url):
      """Parse the URL into the blobkey and option string.

      Args:
        url: a url as a string.

      Returns:
        (blob_key, option) tuple parsed out of the URL.
      """
      path = urlparse.urlsplit(url)[2]
      match = re.search('/_ah/img/([-\\w:]+)([=]*)([-\\w]+)?', path)
      if not match or not match.group(1):
        raise ValueError, 'Failed to parse image url.'
      options = ''
      blobkey = match.group(1)
      if match.group(3):
        if match.group(2):
          blobkey = ''.join([blobkey, match.group(2)[1:]])
        options = match.group(3)
      elif match.group(2):
        blobkey = ''.join([blobkey, match.group(2)])
      return (blobkey, options)


    def Dispatch(self,
                 request,
                 outfile,
                 base_env_dict=None):
      """Handle GET image serving request.

      This dispatcher handles image requests under the /_ah/img/ path.
      The rest of the path should be a serialized blobkey used to retrieve
      the image from blobstore.

      Args:
        request: The HTTP request.
        outfile: The response file.
        base_env_dict: Dictionary of CGI environment parameters if available.
          Defaults to None.
      """
      try:
        if base_env_dict and base_env_dict['REQUEST_METHOD'] != 'GET':
          raise RuntimeError, 'BlobImage only handles GET requests.'

        blobkey, options = self._ParseUrl(request.relative_url)


        key = datastore.Key.from_path(BLOB_SERVING_URL_KIND,
                                      blobkey,
                                      namespace='')
        try:
          datastore.Get(key)
        except datastore_errors.EntityNotFoundError:
          logging.warning('The blobkey %s has not registered for image '
                          'serving. Please ensure get_serving_url is '
                          'called before attempting to serve blobs.', blobkey)
        image, mime_type = self._TransformImage(blobkey, options)
        output_dict = {'status': 200, 'content_type': mime_type,
                       'data': image}
        outfile.write(BLOBIMAGE_RESPONSE_TEMPLATE % output_dict)
      except ValueError:
        logging.exception('ValueError while serving image.')
        outfile.write('Status: 404\r\n')
      except RuntimeError:
        logging.exception('RuntimeError while serving image.')
        outfile.write('Status: 400\r\n')
      except:


        logging.exception('Exception while serving image.')
        outfile.write('Status: 500\r\n')

  return BlobImageDispatcher(images_stub)
