/*
 * Copyright (c) 2016 Intel Corporation
 *
 * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich
 * 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 Institute 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 INSTITUTE 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 INSTITUTE 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 is part of the Contiki operating system.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "os/mynewt.h"

#include "oic/port/mynewt/config.h"
/* OIC Stack headers */
#include "oic/oc_buffer.h"
#include "oic/oc_ri.h"
#include "messaging/coap/engine.h"

#ifdef OC_CLIENT
#include "oic/oc_client_state.h"
#endif

/*---------------------------------------------------------------------------*/
/*- Internal API ------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
int
coap_receive(struct os_mbuf **mp)
{
    /* static declaration reduces stack peaks and program code size */
    /* this way the packet can be treated as pointer as usual */
    struct os_mbuf *m;
    static struct coap_packet_rx message[1];
    static struct coap_packet response[1];
    static coap_transaction_t *transaction = NULL;
    struct os_mbuf *rsp;
    struct oc_endpoint endpoint; /* XXX */

    erbium_status_code = NO_ERROR;

    OC_LOG(INFO, "CoAP: received datalen=%u\n", OS_MBUF_PKTLEN(*mp));

    memcpy(&endpoint, OC_MBUF_ENDPOINT(*mp),
           oc_endpoint_size(OC_MBUF_ENDPOINT(*mp)));
    erbium_status_code = coap_parse_message(message, mp);
    if (erbium_status_code != NO_ERROR) {
        goto out;
    }

    m = *mp;
/*TODO duplicates suppression, if required by application */
    OC_LOG(DEBUG, "  Parsed: CoAP version: %u, token: 0x%02X%02X, mid: %u\n",
                 message->version, message->token[0], message->token[1],
                 message->mid);
    switch (message->type) {
    case COAP_TYPE_CON:
        OC_LOG(DEBUG, "  type: CON\n");
        break;
    case COAP_TYPE_NON:
        OC_LOG(DEBUG, "  type: NON\n");
        break;
    case COAP_TYPE_ACK:
        OC_LOG(DEBUG, "  type: ACK\n");
        break;
    case COAP_TYPE_RST:
        OC_LOG(DEBUG, "  type: RST\n");
        break;
    default:
        break;
    }

    if (message->code >= COAP_GET && message->code <= COAP_DELETE) {
        /* handle requests */
        switch (message->code) {
        case COAP_GET:
            OC_LOG(DEBUG, "  method: GET\n");
            break;
        case COAP_PUT:
            OC_LOG(DEBUG, "  method: PUT\n");
            break;
        case COAP_POST:
            OC_LOG(DEBUG, "  method: POST\n");
            break;
        case COAP_DELETE:
            OC_LOG(DEBUG, "  method: DELETE\n");
            break;
        }

        OC_LOG(DEBUG, "  Payload: %d bytes\n", message->payload_len);

        /* use transaction buffer for response to confirmable request */
        transaction = coap_new_transaction(message->mid, OC_MBUF_ENDPOINT(m));
        if (!transaction) {
            erbium_status_code = SERVICE_UNAVAILABLE_5_03;
            coap_error_message = "NoFreeTraBuffer";
            goto out;
        }

        uint32_t block_num = 0;
        uint16_t block_size = COAP_MAX_BLOCK_SIZE;
        uint32_t block_offset = 0;
        int32_t new_offset = 0;

        /* prepare response */
        if (message->type == COAP_TYPE_CON) {
            /* reliable CON requests are answered with an ACK */
            coap_init_message(response, COAP_TYPE_ACK, CONTENT_2_05,
                              message->mid);
        } else {
            /* unreliable NON requests are answered with a NON */
            coap_init_message(response, COAP_TYPE_NON, CONTENT_2_05,
                              coap_get_mid());
            /* mirror token */
        }
        if (message->token_len) {
            coap_set_token(response, message->token, message->token_len);
            /* get offset for blockwise transfers */
        }
        if (coap_get_header_block2(message, &block_num, NULL,
                                   &block_size, &block_offset)) {
            OC_LOG(DEBUG, " Blockwise: block request %u (%u/%u) @ %u bytes\n",
                         (unsigned int) block_num, block_size,
                         COAP_MAX_BLOCK_SIZE, (unsigned int) block_offset);
            block_size = MIN(block_size, COAP_MAX_BLOCK_SIZE);
            new_offset = block_offset;
        }

        if (oc_ri_invoke_coap_entity_handler(message, response, &new_offset,
                                             OC_MBUF_ENDPOINT(m))) {
            if (erbium_status_code == NO_ERROR) {
                /*
                 * TODO coap_handle_blockwise(request, response,
                 * start_offset, end_offset);
                 */

                /* resource is unaware of Block1 */
                if (IS_OPTION(message, COAP_OPTION_BLOCK1) &&
                  response->code < BAD_REQUEST_4_00 &&
                  !IS_OPTION(response, COAP_OPTION_BLOCK1)) {
                    OC_LOG(ERROR, " Block1 option NOT IMPLEMENTED\n");

                    erbium_status_code = NOT_IMPLEMENTED_5_01;
                    coap_error_message = "NoBlock1Support";

                    /* client requested Block2 transfer */
                } else if (IS_OPTION(message, COAP_OPTION_BLOCK2)) {

                    /*
                     * Unchanged new_offset indicates that resource is
                     * unaware of blockwise transfer
                     */
                    if (new_offset == block_offset) {
                        OC_LOG(DEBUG, " Block: unaware resource %u/%u\n",
                                     response->payload_len, block_size);
                        if (block_offset >= response->payload_len) {
                            response->code = BAD_OPTION_4_02;
                            rsp = os_msys_get_pkthdr(0, 0);
                            if (rsp) {
                                os_mbuf_copyinto(rsp, 0, "BlockOutOfScope", 15);
                                response->payload_m = rsp;
                                response->payload_len = 15;
                            }
                            /* a const char str[] and sizeof(str)
                               produces larger code size */
                        } else {
                            coap_set_header_block2(response, block_num,
                                         response->payload_len - block_offset >
                                           block_size, block_size);
                            response->payload_len = MIN(response->payload_len -
                                                        block_offset,
                                                        block_size);
                        } /* if(valid offset) */

                        /* resource provides chunk-wise data */
                    } else {
                        OC_LOG(DEBUG, " Block: aware resource, off %d\n",
                                     (int) new_offset);
                        coap_set_header_block2(response, block_num,
                                               new_offset != -1 ||
                                         response->payload_len > block_size,
                                               block_size);

                        if (response->payload_len > block_size) {
                            response->payload_len = block_size;
                        }
                    } /* if(resource aware of blockwise) */

                    /* Resource requested Block2 transfer */
                } else if (new_offset != 0) {
                    OC_LOG(DEBUG, " block: no block option, using block sz %u\n",
                                 COAP_MAX_BLOCK_SIZE);

                    coap_set_header_block2(response, 0, new_offset != -1,
                                           COAP_MAX_BLOCK_SIZE);
                    response->payload_len = MIN(response->payload_len,
                                                COAP_MAX_BLOCK_SIZE);
                } /* blockwise transfer handling */
            }   /* no errors/hooks */
            /* successful service callback */
            /* serialize response */
        }
        if (erbium_status_code == NO_ERROR) {
            if (coap_serialize_message(response, transaction->m)) {
                erbium_status_code = PACKET_SERIALIZATION_ERROR;
            }
            transaction->type = response->type;
        }
    } else { // Fix this
        /* handle responses */
        if (message->type == COAP_TYPE_CON) {
            erbium_status_code = EMPTY_ACK_RESPONSE;
        } else if (message->type == COAP_TYPE_ACK) {
            /* transactions are closed through lookup below */
        } else if (message->type == COAP_TYPE_RST) {
#ifdef OC_SERVER
            /* cancel possible subscriptions */
            coap_remove_observer_by_mid(OC_MBUF_ENDPOINT(m), message->mid);
#endif
        }

        /* Open transaction now cleared for ACK since mid matches */
        if ((transaction = coap_get_transaction_by_mid(message->mid))) {
            coap_clear_transaction(transaction);
        }
        /* if(ACKed transaction) */
        transaction = NULL;

#ifdef OC_CLIENT
        /*
         * ACKs and RSTs sent to oc_ri.. RSTs cleared, ACKs sent to
         * client.
         */
        oc_ri_invoke_client_cb(message, OC_MBUF_ENDPOINT(m));
#endif

    } /* request or response */

out:
    /* if(parsed correctly) */
    if (erbium_status_code == NO_ERROR) {
        if (transaction) { // Server transactions sent from here
            coap_send_transaction(transaction);
        }
    } else if (erbium_status_code == CLEAR_TRANSACTION) {
        OC_LOG(DEBUG, " Clearing transaction for manual response\n");
        /* used in server for separate response */
        coap_clear_transaction(transaction);
    }
#ifdef OC_CLIENT
    else if (erbium_status_code == EMPTY_ACK_RESPONSE) {
        coap_init_message(response, COAP_TYPE_ACK, 0, message->mid);
        struct os_mbuf *m_rsp = oc_allocate_mbuf(&endpoint);
        if (m_rsp) {
            if (!coap_serialize_message(response, m_rsp)) {
                coap_send_message(m_rsp, 0);
            } else {
                os_mbuf_free_chain(m_rsp);
            }
        }
    }
#endif /* OC_CLIENT */
#ifdef OC_SERVER
    else { // framework errors handled here
        coap_message_type_t reply_type = COAP_TYPE_RST;

        coap_clear_transaction(transaction);

        coap_init_message(response, reply_type, SERVICE_UNAVAILABLE_5_03,
                          message->mid);

        struct os_mbuf *m_rsp = oc_allocate_mbuf(&endpoint);
        if (m_rsp) {
            if (!coap_serialize_message(response, m_rsp)) {
                coap_send_message(m_rsp, 0);
            } else {
                os_mbuf_free_chain(m_rsp);
            }
        }
    }
#endif /* OC_SERVER */

    /* if(new data) */
    return erbium_status_code;
}

void
coap_engine_init(void)
{
    coap_init_connection();
    coap_transaction_init();
#ifdef OC_SERVER
#if MYNEWT_VAL(OC_SEPARATE_RESPONSES)
    coap_separate_init();
#endif
    coap_observe_init();
#endif
}
