#!/usr/bin/env python
#
#  Copyright (c) 2016, The OpenThread Authors.
#  All rights reserved.
#
#  Redistribution and use in source and binary forms, with or without
#  modification, are permitted provided that the following conditions are met:
#  1. Redistributions of source code must retain the above copyright
#     notice, this list of conditions and the following disclaimer.
#  2. 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.
#  3. Neither the name of the copyright holder 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 HOLDER 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.
#

import collections
import io
import struct

from binascii import hexlify
from enum import IntEnum


class CoapMessageType(IntEnum):
    CON = 0  # Confirmable
    NON = 1  # Non-confirmable
    ACK = 2  # Acknowledgement
    RST = 3  # Reset


class CoapOptionsTypes(IntEnum):
    IF_MATCH = 1
    URI_HOST = 3
    ETAG = 4
    IF_NOT_MATCH = 5
    URI_PORT = 7
    LOCATION_PATH = 8
    URI_PATH = 11
    CONTENT_FORMAT = 12
    MAX_AGE = 14
    URI_QUERY = 15
    ACCEPT = 17
    LOCATION_QUERY = 20
    PROXY_URI = 35
    PROXY_SCHEME = 39
    SIZE1 = 60


class CoapOptionHeader(object):

    """ Class representing CoAP optiona header. """

    def __init__(self, delta, length):
        self._delta = delta
        self._length = length

    @property
    def delta(self):
        return self._delta

    @property
    def length(self):
        return self._length

    @property
    def is_payload_marker(self):
        return self.delta == 0xf and self.length == 0xf

    @classmethod
    def _read_extended_value(cls, data, value):
        if value == 13:
            return ord(data.read(1)) + 13
        elif value == 14:
            data.read(1)
            return ord(data.read(1)) + 269
        else:
            return value

    @classmethod
    def from_bytes(cls, data):
        initial_byte = ord(data.read(1))

        delta = (initial_byte >> 4) & 0xf
        length = initial_byte & 0xf

        delta = cls._read_extended_value(data, delta)
        length = cls._read_extended_value(data, length)

        return cls(delta, length)


class CoapOption(object):

    """ Class representing CoAP option. """

    def __init__(self, _type, value):
        self._type = _type
        self._value = value

    @property
    def type(self):
        return self._type

    @property
    def value(self):
        return self._value

    def __repr__(self):
        return "CoapOption(type={}, value={})".format(self.type, hexlify(self.value))


class CoapOptionsFactory(object):

    """ Factory that produces CoAP options. """

    def parse(self, data, message_info):
        options = []

        _type = 0
        while data.tell() < len(data.getvalue()):
            option_header = CoapOptionHeader.from_bytes(data)
            if option_header.is_payload_marker:
                break

            _type += option_header.delta
            value = data.read(option_header.length)

            option = CoapOption(_type, value)
            options.append(option)

        return options


class CoapCode(object):

    """ Class representing CoAP code. """

    def __init__(self, code):
        self._code = code

    @property
    def code(self):
        return self._code

    @property
    def _class(self):
        return (self.code >> 5) & 0x7

    @property
    def detail(self):
        return self.code & 0x1f

    @classmethod
    def from_class_and_detail(cls, _class, detail):
        return cls(((_class & 0x7) << 5) | (detail & 0x1f))

    @classmethod
    def from_dotted(cls, dotted_str):
        _class, detail = dotted_str.split(".")
        return cls.from_class_and_detail(int(_class), int(detail))

    def is_equal_dotted(self, dotted_code):
        other = self.from_dotted(dotted_code)
        return self.code == other.code

    @property
    def dotted(self):
        return ".".join(["{:01d}".format(self._class), "{:02d}".format(self.detail)])

    def __eq__(self, other):
        if isinstance(other, int):
            return self.code == other

        elif isinstance(other, str):
            return self.is_equal_dotted(other)

        elif isinstance(other, self.__class__):
            return self.code == other.code

        else:
            raise TypeError("Could not compare {} and {}".format(type(self), type(other)))

    def __repr__(self):
        return self.dotted


class CoapMessage(object):

    """ Class representing CoAP message. """

    def __init__(self, version, _type, code, message_id, token, options, payload, uri_path=None):
        self._version = version
        self._type = _type
        self._code = code
        self._message_id = message_id
        self._token = token
        self._options = options
        self._payload = payload
        self._uri_path = uri_path

    @property
    def version(self):
        return self._version

    @property
    def type(self):
        return self._type

    @property
    def code(self):
        return self._code

    @property
    def message_id(self):
        return self._message_id

    @property
    def token(self):
        return self._token

    @property
    def tkl(self):
        return len(self._token)

    @property
    def options(self):
        return self._options

    @property
    def payload(self):
        return self._payload

    @property
    def uri_path(self):
        return self._uri_path

    def __repr__(self):
        options_str = ", ".join([repr(opt) for opt in self.options])
        return "CoapMessage(version={}, type={}, code={}, message_id={}, token={}, options=[{}], payload={}, uri-path='{}')".format(
            self.version, CoapMessageType.name[self.type], self.code, self.message_id, hexlify(self.token),
            options_str, self.payload, self.uri_path)


class CoapMessageProxy(object):

    """ Proxy class of CoAP message. 

    The main idea behind this class is to delay parsing payload. Due to architecture of the existing solution 
    it is possible to process confirmation message before a request message. In such case it is not possible 
    to get URI path to get proper payload parser.
    """

    def __init__(self, coap_message, message_info, mid_to_uri_path_binder, uri_path_based_payload_factories):
        self._coap_message = coap_message
        self._message_info = message_info
        self._mid_to_uri_path_binder = mid_to_uri_path_binder
        self._uri_path_based_payload_factories = uri_path_based_payload_factories

    @property
    def version(self):
        return self._coap_message.version

    @property
    def type(self):
        return self._coap_message.type

    @property
    def code(self):
        return self._coap_message.code

    @property
    def message_id(self):
        return self._coap_message.message_id

    @property
    def token(self):
        return self._coap_message.token

    @property
    def tkl(self):
        return self._coap_message.tkl

    @property
    def options(self):
        return self._coap_message.options

    @property
    def payload(self):
        try:
            binded_uri_path = self._mid_to_uri_path_binder.get_uri_path_for(self.message_id, self.token)

            factory = self._uri_path_based_payload_factories[binded_uri_path]

            return factory.parse(io.BytesIO(self._coap_message.payload), self._message_info)

        except RuntimeError:
            return self._coap_message.payload

    @property
    def uri_path(self):
        return self._coap_message.uri_path

    def __repr__(self):
        options_str = ", ".join([repr(opt) for opt in self.options])
        return "CoapMessageProxy(version={}, type={}, code={}, message_id={}, token={}, options=[{}], payload={}, uri-path='{}')".format(
            self.version, self.type, self.code, self.message_id, hexlify(self.token),
            options_str, self.payload, self.uri_path)


class CoapMessageIdToUriPathBinder:

    """ Class binds message id and token with URI path. """

    def __init__(self):
        self._uri_path_binds = collections.defaultdict(collections.defaultdict)

    def add_uri_path_for(self, message_id, token, uri_path):
        self._uri_path_binds[message_id][hexlify(token)] = uri_path

    def get_uri_path_for(self, message_id, token):
        try:
            return self._uri_path_binds[message_id][hexlify(token)]
        except KeyError:
            raise RuntimeError("Could not find URI PATH for message_id: {} and token: {}".format(
                message_id, hexlify(token)))


class CoapMessageFactory(object):

    """ Factory that produces CoAP messages. """

    def __init__(self, options_factory, uri_path_based_payload_factories, message_id_to_uri_path_binder):
        self._options_factory = options_factory
        self._uri_path_based_payload_factories = uri_path_based_payload_factories
        self._mid_to_uri_path_binder = message_id_to_uri_path_binder

    def _uri_path_from(self, options):
        uri_path_options = []

        for option in options:
            if option.type == CoapOptionsTypes.URI_PATH:
                uri_path_options.append(option.value.decode("utf-8"))

        if not uri_path_options:
            return None

        return "/" + "/".join(uri_path_options)

    def _parse_initial_byte(self, data, message_info):
        initial_byte = ord(data.read(1))

        version = (initial_byte >> 6) & 0x3
        _type = CoapMessageType((initial_byte >> 4) & 0x3)
        token_length = initial_byte & 0xf

        return version, _type, token_length

    def parse(self, data, message_info):
        version, _type, token_length = self._parse_initial_byte(data, message_info)

        code = CoapCode(ord(data.read(1)))
        message_id = struct.unpack(">H", data.read(2))[0]
        token = data.read(token_length)

        options = self._options_factory.parse(data, message_info)

        uri_path = self._uri_path_from(options)
        if uri_path is not None:
            self._mid_to_uri_path_binder.add_uri_path_for(message_id, token, uri_path)

        coap_message = CoapMessage(version, _type, code, message_id, token, options, data.read(), uri_path)

        return CoapMessageProxy(coap_message, message_info, self._mid_to_uri_path_binder, self._uri_path_based_payload_factories)
