#!/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.
#
"""Channel support classes.

Classes:

  CreateChannelDispatcher:
    Creates a dispatcher that is added to dispatcher chain.  Handles polls from
    the client to retrieve messages for a given channel.
"""



import cgi
import os
import urlparse

from google.appengine.api.channel.channel_service_stub import InvalidTokenError
from google.appengine.api.channel.channel_service_stub import TokenTimedOutError



CHANNEL_POLL_PATTERN = '/_ah/channel/dev(?:/.*)?'


CHANNEL_JSAPI_PATTERN = '/_ah/channel/jsapi'


def CreateChannelDispatcher(channel_service_stub):
  """Function to create channel dispatcher.

  Args:
    channel_service_stub: The service stub responsible for creating channels and
      sending messages. This stub stores messages destined for channels, so we
      query it when the client polls the _ah/channel/ dispatcher.

  Returns:
    New dispatcher capable of handling client polls for channel messages.
  """



  from google.appengine.tools import old_dev_appserver

  class ChannelDispatcher(old_dev_appserver.URLDispatcher):
    """Dispatcher that handles channel polls."""

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

      Args:
        channel_service_stub: The channel service that receives channel messages
        from the application.
      """
      self._channel_service_stub = channel_service_stub


    def Dispatch(self,
                 request,
                 outfile,
                 base_env_dict=None):
      """Handle post dispatch.

      This dispatcher handles requests under the /_ah/channel/ path. Currently
      it handles 3 sub-paths:
        connect: place-holder for parity with the java dev channel.
        poll:    return pending messages for the channel identified by the
                 channel parameter.
        jsapi:   return the javascript library to retrieve messages for the
                 channel.

      Args:
        request: The HTTP request.
        outfile: The response file.
        base_env_dict: Dictionary of CGI environment parameters if available.
          Defaults to None.
      """

      (unused_scheme, unused_netloc,
       path, query,
       unused_fragment) = urlparse.urlsplit(request.relative_url)
      param_dict = cgi.parse_qs(query, True)

      page = path.rsplit('/', 1)[-1]

      if page == 'jsapi':
        path = os.path.join(os.path.dirname(__file__), 'dev-channel-js.js')
        outfile.write('Status: 200\r\n')
        outfile.write('Content-type: text/javascript\r\n\r\n')
        outfile.write(open(path).read())
      elif page == 'dev':
        token = param_dict['channel'][0]

        token_error = None
        try:
          self._channel_service_stub.validate_token_and_extract_client_id(token)


        except InvalidTokenError:
          token_error = 'Invalid+token.'
        except TokenTimedOutError:
          token_error = 'Token+timed+out.'

        if token_error is not None:
          outfile.write('Status: 401 %s\r\n\r\n' % token_error)
          return

        outfile.write('Status: 200\r\n')
        outfile.write('\r\n')
        command = param_dict['command'][0]

        if command == 'connect':
          self._channel_service_stub.connect_channel(token)
          outfile.write('1')
        elif command == 'poll':
          self._channel_service_stub.connect_channel(token)
          if self._channel_service_stub.has_channel_messages(token):
            outfile.write(self._channel_service_stub.pop_first_message(token))

  return ChannelDispatcher(channel_service_stub)
