# Copyright 2012, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
#     * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


"""This file must not depend on any module specific to the WebSocket protocol.
"""


from mod_pywebsocket import http_header_util


# Additional log level definitions.
LOGLEVEL_FINE = 9

# Constants indicating WebSocket protocol version.
VERSION_HIXIE75 = -1
VERSION_HYBI00 = 0
VERSION_HYBI01 = 1
VERSION_HYBI02 = 2
VERSION_HYBI03 = 2
VERSION_HYBI04 = 4
VERSION_HYBI05 = 5
VERSION_HYBI06 = 6
VERSION_HYBI07 = 7
VERSION_HYBI08 = 8
VERSION_HYBI09 = 8
VERSION_HYBI10 = 8
VERSION_HYBI11 = 8
VERSION_HYBI12 = 8
VERSION_HYBI13 = 13
VERSION_HYBI14 = 13
VERSION_HYBI15 = 13
VERSION_HYBI16 = 13
VERSION_HYBI17 = 13

# Constants indicating WebSocket protocol latest version.
VERSION_HYBI_LATEST = VERSION_HYBI13

# Port numbers
DEFAULT_WEB_SOCKET_PORT = 80
DEFAULT_WEB_SOCKET_SECURE_PORT = 443

# Schemes
WEB_SOCKET_SCHEME = 'ws'
WEB_SOCKET_SECURE_SCHEME = 'wss'

# Frame opcodes defined in the spec.
OPCODE_CONTINUATION = 0x0
OPCODE_TEXT = 0x1
OPCODE_BINARY = 0x2
OPCODE_CLOSE = 0x8
OPCODE_PING = 0x9
OPCODE_PONG = 0xa

# UUIDs used by HyBi 04 and later opening handshake and frame masking.
WEBSOCKET_ACCEPT_UUID = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'

# Opening handshake header names and expected values.
UPGRADE_HEADER = 'Upgrade'
WEBSOCKET_UPGRADE_TYPE = 'websocket'
WEBSOCKET_UPGRADE_TYPE_HIXIE75 = 'WebSocket'
CONNECTION_HEADER = 'Connection'
UPGRADE_CONNECTION_TYPE = 'Upgrade'
HOST_HEADER = 'Host'
ORIGIN_HEADER = 'Origin'
SEC_WEBSOCKET_ORIGIN_HEADER = 'Sec-WebSocket-Origin'
SEC_WEBSOCKET_KEY_HEADER = 'Sec-WebSocket-Key'
SEC_WEBSOCKET_ACCEPT_HEADER = 'Sec-WebSocket-Accept'
SEC_WEBSOCKET_VERSION_HEADER = 'Sec-WebSocket-Version'
SEC_WEBSOCKET_PROTOCOL_HEADER = 'Sec-WebSocket-Protocol'
SEC_WEBSOCKET_EXTENSIONS_HEADER = 'Sec-WebSocket-Extensions'
SEC_WEBSOCKET_DRAFT_HEADER = 'Sec-WebSocket-Draft'
SEC_WEBSOCKET_KEY1_HEADER = 'Sec-WebSocket-Key1'
SEC_WEBSOCKET_KEY2_HEADER = 'Sec-WebSocket-Key2'
SEC_WEBSOCKET_LOCATION_HEADER = 'Sec-WebSocket-Location'

# Extensions
DEFLATE_STREAM_EXTENSION = 'deflate-stream'
DEFLATE_FRAME_EXTENSION = 'deflate-frame'
PERFRAME_COMPRESSION_EXTENSION = 'perframe-compress'
PERMESSAGE_COMPRESSION_EXTENSION = 'permessage-compress'
X_WEBKIT_DEFLATE_FRAME_EXTENSION = 'x-webkit-deflate-frame'
MUX_EXTENSION = 'mux_DO_NOT_USE'

# Status codes
# Code STATUS_NO_STATUS_RECEIVED, STATUS_ABNORMAL_CLOSURE, and
# STATUS_TLS_HANDSHAKE are pseudo codes to indicate specific error cases.
# Could not be used for codes in actual closing frames.
# Application level errors must use codes in the range
# STATUS_USER_REGISTERED_BASE to STATUS_USER_PRIVATE_MAX. The codes in the
# range STATUS_USER_REGISTERED_BASE to STATUS_USER_REGISTERED_MAX are managed
# by IANA. Usually application must define user protocol level errors in the
# range STATUS_USER_PRIVATE_BASE to STATUS_USER_PRIVATE_MAX.
STATUS_NORMAL_CLOSURE = 1000
STATUS_GOING_AWAY = 1001
STATUS_PROTOCOL_ERROR = 1002
STATUS_UNSUPPORTED_DATA = 1003
STATUS_NO_STATUS_RECEIVED = 1005
STATUS_ABNORMAL_CLOSURE = 1006
STATUS_INVALID_FRAME_PAYLOAD_DATA = 1007
STATUS_POLICY_VIOLATION = 1008
STATUS_MESSAGE_TOO_BIG = 1009
STATUS_MANDATORY_EXTENSION = 1010
STATUS_INTERNAL_SERVER_ERROR = 1011
STATUS_TLS_HANDSHAKE = 1015
STATUS_USER_REGISTERED_BASE = 3000
STATUS_USER_REGISTERED_MAX = 3999
STATUS_USER_PRIVATE_BASE = 4000
STATUS_USER_PRIVATE_MAX = 4999
# Following definitions are aliases to keep compatibility. Applications must
# not use these obsoleted definitions anymore.
STATUS_NORMAL = STATUS_NORMAL_CLOSURE
STATUS_UNSUPPORTED = STATUS_UNSUPPORTED_DATA
STATUS_CODE_NOT_AVAILABLE = STATUS_NO_STATUS_RECEIVED
STATUS_ABNORMAL_CLOSE = STATUS_ABNORMAL_CLOSURE
STATUS_INVALID_FRAME_PAYLOAD = STATUS_INVALID_FRAME_PAYLOAD_DATA
STATUS_MANDATORY_EXT = STATUS_MANDATORY_EXTENSION

# HTTP status codes
HTTP_STATUS_BAD_REQUEST = 400
HTTP_STATUS_FORBIDDEN = 403
HTTP_STATUS_NOT_FOUND = 404


def is_control_opcode(opcode):
    return (opcode >> 3) == 1


class ExtensionParameter(object):
    """Holds information about an extension which is exchanged on extension
    negotiation in opening handshake.
    """

    def __init__(self, name):
        self._name = name
        # TODO(tyoshino): Change the data structure to more efficient one such
        # as dict when the spec changes to say like
        # - Parameter names must be unique
        # - The order of parameters is not significant
        self._parameters = []

    def name(self):
        return self._name

    def add_parameter(self, name, value):
        self._parameters.append((name, value))

    def get_parameters(self):
        return self._parameters

    def get_parameter_names(self):
        return [name for name, unused_value in self._parameters]

    def has_parameter(self, name):
        for param_name, param_value in self._parameters:
            if param_name == name:
                return True
        return False

    def get_parameter_value(self, name):
        for param_name, param_value in self._parameters:
            if param_name == name:
                return param_value


class ExtensionParsingException(Exception):
    def __init__(self, name):
        super(ExtensionParsingException, self).__init__(name)


def _parse_extension_param(state, definition, allow_quoted_string):
    param_name = http_header_util.consume_token(state)

    if param_name is None:
        raise ExtensionParsingException('No valid parameter name found')

    http_header_util.consume_lwses(state)

    if not http_header_util.consume_string(state, '='):
        definition.add_parameter(param_name, None)
        return

    http_header_util.consume_lwses(state)

    if allow_quoted_string:
        # TODO(toyoshim): Add code to validate that parsed param_value is token
        param_value = http_header_util.consume_token_or_quoted_string(state)
    else:
        param_value = http_header_util.consume_token(state)
    if param_value is None:
        raise ExtensionParsingException(
            'No valid parameter value found on the right-hand side of '
            'parameter %r' % param_name)

    definition.add_parameter(param_name, param_value)


def _parse_extension(state, allow_quoted_string):
    extension_token = http_header_util.consume_token(state)
    if extension_token is None:
        return None

    extension = ExtensionParameter(extension_token)

    while True:
        http_header_util.consume_lwses(state)

        if not http_header_util.consume_string(state, ';'):
            break

        http_header_util.consume_lwses(state)

        try:
            _parse_extension_param(state, extension, allow_quoted_string)
        except ExtensionParsingException, e:
            raise ExtensionParsingException(
                'Failed to parse parameter for %r (%r)' %
                (extension_token, e))

    return extension


def parse_extensions(data, allow_quoted_string=False):
    """Parses Sec-WebSocket-Extensions header value returns a list of
    ExtensionParameter objects.

    Leading LWSes must be trimmed.
    """

    state = http_header_util.ParsingState(data)

    extension_list = []
    while True:
        extension = _parse_extension(state, allow_quoted_string)
        if extension is not None:
            extension_list.append(extension)

        http_header_util.consume_lwses(state)

        if http_header_util.peek(state) is None:
            break

        if not http_header_util.consume_string(state, ','):
            raise ExtensionParsingException(
                'Failed to parse Sec-WebSocket-Extensions header: '
                'Expected a comma but found %r' %
                http_header_util.peek(state))

        http_header_util.consume_lwses(state)

    if len(extension_list) == 0:
        raise ExtensionParsingException(
            'No valid extension entry found')

    return extension_list


def format_extension(extension):
    """Formats an ExtensionParameter object."""

    formatted_params = [extension.name()]
    for param_name, param_value in extension.get_parameters():
        if param_value is None:
            formatted_params.append(param_name)
        else:
            quoted_value = http_header_util.quote_if_necessary(param_value)
            formatted_params.append('%s=%s' % (param_name, quoted_value))
    return '; '.join(formatted_params)


def format_extensions(extension_list):
    """Formats a list of ExtensionParameter objects."""

    formatted_extension_list = []
    for extension in extension_list:
        formatted_extension_list.append(format_extension(extension))
    return ', '.join(formatted_extension_list)


# vi:sts=4 sw=4 et
