/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

#include <assert.h>
#include <string.h>
#include <stdint.h>

#include "os/mynewt.h"

#if (MYNEWT_VAL(OC_TRANSPORT_GATT) == 1)

#include <stats/stats.h>
#include "oic/oc_gatt.h"
#include "oic/oc_log.h"
#include "oic/oc_ri.h"
#include "oic/messaging/coap/coap.h"
#include "oic/port/oc_connectivity.h"
#include "oic/port/mynewt/ble.h"
#include "host/ble_hs.h"
#include "services/gap/ble_svc_gap.h"
#include "services/gatt/ble_svc_gatt.h"

static uint8_t oc_ep_gatt_size(const struct oc_endpoint *oe);
static void oc_send_buffer_gatt(struct os_mbuf *m);
static char *oc_log_ep_gatt(char *ptr, int maxlen, const struct oc_endpoint *);
enum oc_resource_properties
oc_get_trans_security_gatt(const struct oc_endpoint *oe_ble);
static int oc_connectivity_init_gatt(void);
void oc_connectivity_shutdown_gatt(void);

static const struct oc_transport oc_gatt_transport = {
    .ot_flags = OC_TRANSPORT_USE_TCP,
    .ot_ep_size = oc_ep_gatt_size,
    .ot_tx_ucast = oc_send_buffer_gatt,
    .ot_tx_mcast = oc_send_buffer_gatt,
    .ot_get_trans_security = oc_get_trans_security_gatt,
    .ot_ep_str = oc_log_ep_gatt,
    .ot_init = oc_connectivity_init_gatt,
    .ot_shutdown = oc_connectivity_shutdown_gatt
};

static uint8_t oc_gatt_transport_id;

/* OIC Transport Profile GATT */

/* unsecure service UUID */
/* ADE3D529-C784-4F63-A987-EB69F70EE816 */
static const ble_uuid128_t oc_gatt_unsec_svc_uuid =
    BLE_UUID128_INIT(OC_GATT_UNSEC_SVC_UUID);

/* unsecure request characteristic UUID */
/* AD7B334F-4637-4B86-90B6-9D787F03D218 */
static const ble_uuid128_t oc_gatt_unsec_req_chr_uuid =
    BLE_UUID128_INIT(OC_GATT_UNSEC_REQ_CHR_UUID);

/* response characteristic UUID */
/* E9241982-4580-42C4-8831-95048216B256 */
static const ble_uuid128_t oc_gatt_unsec_rsp_chr_uuid =
    BLE_UUID128_INIT(OC_GATT_UNSEC_RSP_CHR_UUID);

/* secure service UUID. */
/* 0xfe18 */
static const ble_uuid16_t oc_gatt_sec_svc_uuid =
    BLE_UUID16_INIT(OC_GATT_SEC_SVC_UUID);

/* secure request characteristic UUID. */
/* 0x1000 */
static const ble_uuid16_t oc_gatt_sec_req_chr_uuid =
    BLE_UUID16_INIT(OC_GATT_SEC_REQ_CHR_UUID);

/* secure response characteristic UUID. */
/* 0x1001 */
static const ble_uuid16_t oc_gatt_sec_rsp_chr_uuid =
    BLE_UUID16_INIT(OC_GATT_SEC_RSP_CHR_UUID);

STATS_SECT_START(oc_ble_stats)
    STATS_SECT_ENTRY(iframe)
    STATS_SECT_ENTRY(iseg)
    STATS_SECT_ENTRY(ibytes)
    STATS_SECT_ENTRY(ierr)
    STATS_SECT_ENTRY(oframe)
    STATS_SECT_ENTRY(oseg)
    STATS_SECT_ENTRY(obytes)
    STATS_SECT_ENTRY(oerr)
STATS_SECT_END
STATS_SECT_DECL(oc_ble_stats) oc_ble_stats;
STATS_NAME_START(oc_ble_stats)
    STATS_NAME(oc_ble_stats, iframe)
    STATS_NAME(oc_ble_stats, iseg)
    STATS_NAME(oc_ble_stats, ibytes)
    STATS_NAME(oc_ble_stats, ierr)
    STATS_NAME(oc_ble_stats, oframe)
    STATS_NAME(oc_ble_stats, oseg)
    STATS_NAME(oc_ble_stats, obytes)
    STATS_NAME(oc_ble_stats, oerr)
STATS_NAME_END(oc_ble_stats)

static STAILQ_HEAD(, os_mbuf_pkthdr) oc_ble_reass_q;

#if (MYNEWT_VAL(OC_SERVER) == 1)
/*
 * BLE nmgr attribute handles for service
 */
#define OC_BLE_SRV_CNT		2
static struct {
    uint16_t req;
    uint16_t rsp;
} oc_ble_srv_handles[OC_BLE_SRV_CNT];

static int oc_gatt_chr_access(uint16_t conn_handle, uint16_t attr_handle,
                   struct ble_gatt_access_ctxt *ctxt, void *arg);

static const struct ble_gatt_svc_def oc_gatt_svr_svcs[] = { {
        /* Service: iotivity */
        .type = BLE_GATT_SVC_TYPE_PRIMARY,
        .uuid = &oc_gatt_unsec_svc_uuid.u,
        .characteristics = (struct ble_gatt_chr_def[]) {
            {
                /* Characteristic: Request */
                .uuid = &oc_gatt_unsec_req_chr_uuid.u,
                .access_cb = oc_gatt_chr_access,
                .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_WRITE_NO_RSP,
                .val_handle = &oc_ble_srv_handles[0].req,
            },{
                /* Characteristic: Response */
                .uuid = &oc_gatt_unsec_rsp_chr_uuid.u,
                .access_cb = oc_gatt_chr_access,
                .flags = BLE_GATT_CHR_F_NOTIFY,
                .val_handle = &oc_ble_srv_handles[0].rsp,
            },{
                0, /* No more characteristics in this service */
            }
        },
    },{
        /* Service: CoAP-over-BLE */
        .type = BLE_GATT_SVC_TYPE_PRIMARY,
        .uuid = &oc_gatt_sec_svc_uuid.u,
        .characteristics = (struct ble_gatt_chr_def[]) {
            {
                /* Characteristic: Request */
                .uuid = &oc_gatt_sec_req_chr_uuid.u,
                .access_cb = oc_gatt_chr_access,
                .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_WRITE_NO_RSP,
                .val_handle = &oc_ble_srv_handles[1].req,
            },{
                /* Characteristic: Response */
                .uuid = &oc_gatt_sec_rsp_chr_uuid.u,
                .access_cb = oc_gatt_chr_access,
                .flags = BLE_GATT_CHR_F_NOTIFY,
                .val_handle = &oc_ble_srv_handles[1].rsp,
            },{
                0, /* No more characteristics in this service */
            }
        },
    },
    {
        0, /* No more services */
    },
};

/*
 * Look up service index based on characteristic handle from request.
 */
static int
oc_ble_req_attr_to_idx(uint16_t attr_handle)
{
    int i;

    for (i = 0; i < OC_BLE_SRV_CNT; i++) {
        if (oc_ble_srv_handles[i].req == attr_handle) {
            return i;
        }
    }
    return -1;
}

static uint8_t
oc_ep_gatt_size(const struct oc_endpoint *oe)
{
    return sizeof(struct oc_endpoint_ble);
}

static char *
oc_log_ep_gatt(char *ptr, int maxlen, const struct oc_endpoint *oe)
{
    struct oc_endpoint_ble *oe_ble = (struct oc_endpoint_ble *)oe;

    snprintf(ptr, maxlen, "ble %u", oe_ble->conn_handle);
    return ptr;
}

int
oc_ble_reass(struct os_mbuf *om1, uint16_t conn_handle, uint8_t srv_idx)
{
    struct os_mbuf_pkthdr *pkt1;
    struct oc_endpoint_ble *oe_ble;
    struct os_mbuf *om2;
    struct os_mbuf_pkthdr *pkt2;
    uint8_t hdr[6]; /* sizeof(coap_tcp_hdr32) */

    pkt1 = OS_MBUF_PKTHDR(om1);
    assert(pkt1);

    STATS_INC(oc_ble_stats, iseg);
    STATS_INCN(oc_ble_stats, ibytes, pkt1->omp_len);

    OC_LOG(DEBUG, "oc_gatt rx seg %u-%x-%u\n", conn_handle,
                 (unsigned)pkt1, pkt1->omp_len);

    STAILQ_FOREACH(pkt2, &oc_ble_reass_q, omp_next) {
        om2 = OS_MBUF_PKTHDR_TO_MBUF(pkt2);
        oe_ble = (struct oc_endpoint_ble *)OC_MBUF_ENDPOINT(om2);
        if (conn_handle == oe_ble->conn_handle && srv_idx == oe_ble->srv_idx) {
            /*
             * Data from same connection. Append.
             */
            os_mbuf_concat(om2, om1);
            os_mbuf_copydata(om2, 0, sizeof(hdr), hdr);

            if (coap_tcp_msg_size(hdr, sizeof(hdr)) <= pkt2->omp_len) {
                STAILQ_REMOVE(&oc_ble_reass_q, pkt2, os_mbuf_pkthdr, omp_next);
                STATS_INC(oc_ble_stats, iframe);
                oc_recv_message(om2);
            }
            pkt1 = NULL;
            break;
        }
    }
    if (pkt1) {
        /*
         * New frame, need to add oc_endpoint_ble in the front.
         * Check if there is enough space available. If not, allocate a
         * new pkthdr.
         */
        if (OS_MBUF_USRHDR_LEN(om1) < sizeof(struct oc_endpoint_ble)) {
            om2 = os_msys_get_pkthdr(0, sizeof(struct oc_endpoint_ble));
            if (!om2) {
                OC_LOG(ERROR, "oc_gatt_rx: Could not allocate mbuf\n");
                STATS_INC(oc_ble_stats, ierr);
                return -1;
            }
            OS_MBUF_PKTHDR(om2)->omp_len = pkt1->omp_len;
            SLIST_NEXT(om2, om_next) = om1;
        } else {
            om2 = om1;
        }
        oe_ble = (struct oc_endpoint_ble *)OC_MBUF_ENDPOINT(om2);
        oe_ble->ep.oe_type = oc_gatt_transport_id;
        oe_ble->ep.oe_flags = 0;
        oe_ble->srv_idx = srv_idx;
        oe_ble->conn_handle = conn_handle;
        pkt2 = OS_MBUF_PKTHDR(om2);

        os_mbuf_copydata(om2, 0, sizeof(hdr), hdr);
        if (coap_tcp_msg_size(hdr, sizeof(hdr)) > pkt2->omp_len) {
            STAILQ_INSERT_TAIL(&oc_ble_reass_q, pkt2, omp_next);
        } else {
            STATS_INC(oc_ble_stats, iframe);
            oc_recv_message(om2);
        }
    }
    return 0;
}

static int
oc_gatt_chr_access(uint16_t conn_handle, uint16_t attr_handle,
                   struct ble_gatt_access_ctxt *ctxt, void *arg)
{
    struct os_mbuf *m;
    int rc;
    int srv_idx;

    switch (ctxt->op) {
    case BLE_GATT_ACCESS_OP_WRITE_CHR:
        m = ctxt->om;

        srv_idx = oc_ble_req_attr_to_idx(attr_handle);
        assert(srv_idx >= 0);
        rc = oc_ble_reass(m, conn_handle, srv_idx);
        if (rc) {
            return BLE_ATT_ERR_INSUFFICIENT_RES;
        }

        /* tell nimble we are keeping the mbuf */
        ctxt->om = NULL;

        break;
    default:
        assert(0);
        return BLE_ATT_ERR_UNLIKELY;
    }
    return 0;
}
#endif

int
oc_ble_coap_gatt_srv_init(void)
{
#if (MYNEWT_VAL(OC_SERVER) == 1)
    int rc;

    rc = ble_gatts_count_cfg(oc_gatt_svr_svcs);
    assert(rc == 0);

    rc = ble_gatts_add_svcs(oc_gatt_svr_svcs);
    assert(rc == 0);
#endif
    (void)stats_init_and_reg(STATS_HDR(oc_ble_stats),
      STATS_SIZE_INIT_PARMS(oc_ble_stats, STATS_SIZE_32),
      STATS_NAME_INIT_PARMS(oc_ble_stats), "oc_ble");
    return 0;
}

void
oc_ble_coap_conn_new(uint16_t conn_handle)
{
    OC_LOG(DEBUG, "oc_gatt newconn %x\n", conn_handle);
}

void
oc_ble_coap_conn_del(uint16_t conn_handle)
{
    struct os_mbuf_pkthdr *pkt;
    struct os_mbuf *m;
    struct oc_endpoint_ble *oe_ble;

    OC_LOG(DEBUG, "oc_gatt endconn %x\n", conn_handle);
    STAILQ_FOREACH(pkt, &oc_ble_reass_q, omp_next) {
        m = OS_MBUF_PKTHDR_TO_MBUF(pkt);
        oe_ble = (struct oc_endpoint_ble *)OC_MBUF_ENDPOINT(m);
        if (oe_ble->conn_handle == conn_handle) {
            STAILQ_REMOVE(&oc_ble_reass_q, pkt, os_mbuf_pkthdr, omp_next);
            os_mbuf_free_chain(m);
            break;
        }
    }
}

int
oc_connectivity_init_gatt(void)
{
    STAILQ_INIT(&oc_ble_reass_q);
    return 0;
}

void
oc_connectivity_shutdown_gatt(void)
{
    /* there is not unregister for BLE */
}

#if (MYNEWT_VAL(OC_SERVER) == 1)
static int
oc_ble_frag(struct os_mbuf *m, uint16_t mtu)
{
    struct os_mbuf_pkthdr *pkt;
    struct os_mbuf *n;
    uint16_t off, blk;

    pkt = OS_MBUF_PKTHDR(m);
    if (pkt->omp_len <= mtu) {
        STAILQ_NEXT(pkt, omp_next) = NULL;
        return 0;
    }

    off = pkt->omp_len - (pkt->omp_len % mtu);
    while (off >= mtu) {
        n = os_msys_get_pkthdr(mtu, 0);
        if (!n) {
            goto err;
        }
        STAILQ_NEXT(OS_MBUF_PKTHDR(n), omp_next) = STAILQ_NEXT(pkt, omp_next);
        STAILQ_NEXT(pkt, omp_next) = OS_MBUF_PKTHDR(n);

        blk = pkt->omp_len - off;
        if (os_mbuf_appendfrom(n, m, off, blk)) {
            goto err;
        }
        off -= mtu;
        os_mbuf_adj(m, -blk);
    }
    return 0;
err:
    pkt = OS_MBUF_PKTHDR(m);
    while (1) {
        pkt = STAILQ_NEXT(pkt, omp_next);
        os_mbuf_free_chain(m);
        if (!pkt) {
            break;
        }
        m = OS_MBUF_PKTHDR_TO_MBUF(pkt);
    };
    return -1;
}
#endif

void
oc_send_buffer_gatt(struct os_mbuf *m)
{
#if (MYNEWT_VAL(OC_SERVER) == 1)
    struct oc_endpoint_ble *oe_ble;
    struct os_mbuf_pkthdr *pkt;
    uint16_t mtu;
    uint16_t conn_handle;
    uint16_t attr_handle;
#endif

#if (MYNEWT_VAL(OC_SERVER) == 1)

    assert(OS_MBUF_USRHDR_LEN(m) >= sizeof(struct oc_endpoint_ble));
    oe_ble = (struct oc_endpoint_ble *)OC_MBUF_ENDPOINT(m);
    conn_handle = oe_ble->conn_handle;

    STATS_INC(oc_ble_stats, oframe);
    STATS_INCN(oc_ble_stats, obytes, OS_MBUF_PKTLEN(m));

    if (oe_ble->srv_idx >= OC_BLE_SRV_CNT) {
        goto err;
    }
    attr_handle = oc_ble_srv_handles[oe_ble->srv_idx].rsp;

    mtu = ble_att_mtu(conn_handle);
    if (mtu < 4) {
        oc_ble_coap_conn_del(conn_handle);
        goto err;
    }
    mtu -= 3; /* # of bytes for ATT notification base */

    if (oc_ble_frag(m, mtu)) {
        STATS_INC(oc_ble_stats, oerr);
        return;
    }
    while (1) {
        STATS_INC(oc_ble_stats, oseg);
        pkt = STAILQ_NEXT(OS_MBUF_PKTHDR(m), omp_next);

        ble_gattc_notify_custom(conn_handle, attr_handle, m);
        if (pkt) {
            m = OS_MBUF_PKTHDR_TO_MBUF(pkt);
        } else {
            break;
        }
    }
    return;

err:
    os_mbuf_free_chain(m);
    STATS_INC(oc_ble_stats, oerr);
#endif
}

/**
 * Retrieves the specified BLE endpoint's transport layer security properties.
 */
oc_resource_properties_t
oc_get_trans_security_gatt(const struct oc_endpoint *oe)
{
    const struct oc_endpoint_ble *oe_ble;
    oc_resource_properties_t props;
    struct ble_gap_conn_desc desc;
    int rc;

    oe_ble = (const struct oc_endpoint_ble *)oe;
    rc = ble_gap_conn_find(oe_ble->conn_handle, &desc);
    if (rc != 0) {
        return 0;
    }

    props = 0;
    if (desc.sec_state.encrypted) {
        props |= OC_TRANS_ENC;
    }
    if (desc.sec_state.authenticated) {
        props |= OC_TRANS_AUTH;
    }

    return props;
}

#endif

void
oc_register_gatt(void)
{
#if (MYNEWT_VAL(OC_TRANSPORT_GATT) == 1)
    oc_gatt_transport_id = oc_transport_register(&oc_gatt_transport);
#endif
}
