/*
 * 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 <stdio.h>
#include <string.h>
#include "os/mynewt.h"
#include "host/ble_hs.h"
#include "host/ble_uuid.h"
#include "blecsc_sens.h"

#define CSC_ERR_CCC_DESC_IMPROPERLY_CONFIGURED  0x81

static const char *manuf_name = "Apache Mynewt";
static const char *model_num = "Mynewt CSC Sensor";

static const uint8_t csc_supported_sensor_locations[] = {
    SENSOR_LOCATION_FRONT_WHEEL,
    SENSOR_LOCATION_REAR_DROPOUT,
    SENSOR_LOCATION_CHAINSTAY,
    SENSOR_LOCATION_REAR_WHEEL
};

static uint8_t sensor_location = SENSOR_LOCATION_REAR_DROPOUT;
static struct ble_csc_measurement_state * measurement_state;
uint16_t csc_measurement_handle;
uint16_t csc_control_point_handle;
uint8_t csc_cp_indication_status;

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

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

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

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

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

static const struct ble_gatt_svc_def gatt_svr_svcs[] = {
    {
        /* Service: Cycling Speed and Cadence */
        .type = BLE_GATT_SVC_TYPE_PRIMARY,
        .uuid = BLE_UUID16_DECLARE(GATT_CSC_UUID),
        .characteristics = (struct ble_gatt_chr_def[]) { {
            /* Characteristic: Cycling Speed and Cadence Measurement */
            .uuid = BLE_UUID16_DECLARE(GATT_CSC_MEASUREMENT_UUID),
            .access_cb = gatt_svr_chr_access_csc_measurement,
            .val_handle = &csc_measurement_handle,
            .flags = BLE_GATT_CHR_F_NOTIFY,
        }, {
            /* Characteristic: Cycling Speed and Cadence features */
            .uuid = BLE_UUID16_DECLARE(GATT_CSC_FEATURE_UUID),
            .access_cb = gatt_svr_chr_access_csc_feature,
            .flags = BLE_GATT_CHR_F_READ,
        }, {
            /* Characteristic: Sensor Location */
            .uuid = BLE_UUID16_DECLARE(GATT_SENSOR_LOCATION_UUID),
            .access_cb = gatt_svr_chr_access_sensor_location,
            .flags = BLE_GATT_CHR_F_READ,
        }, {
            /* Characteristic: SC Control Point*/
            .uuid = BLE_UUID16_DECLARE(GATT_SC_CONTROL_POINT_UUID),
            .access_cb = gatt_svr_chr_access_sc_control_point,
            .val_handle = &csc_control_point_handle,
            .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_INDICATE,
        }, {
            0, /* No more characteristics in this service */
        }, }
    },

    {
        /* Service: Device Information */
        .type = BLE_GATT_SVC_TYPE_PRIMARY,
        .uuid = BLE_UUID16_DECLARE(GATT_DEVICE_INFO_UUID),
        .characteristics = (struct ble_gatt_chr_def[]) { {
            /* Characteristic: * Manufacturer name */
            .uuid = BLE_UUID16_DECLARE(GATT_MANUFACTURER_NAME_UUID),
            .access_cb = gatt_svr_chr_access_device_info,
            .flags = BLE_GATT_CHR_F_READ,
        }, {
            /* Characteristic: Model number string */
            .uuid = BLE_UUID16_DECLARE(GATT_MODEL_NUMBER_UUID),
            .access_cb = gatt_svr_chr_access_device_info,
            .flags = BLE_GATT_CHR_F_READ,
        }, {
            0, /* No more characteristics in this service */
        }, }
    },

    {
        0, /* No more services */
    },
};

static int
gatt_svr_chr_access_csc_measurement(uint16_t conn_handle, uint16_t attr_handle,
                                  struct ble_gatt_access_ctxt *ctxt, void *arg)
{
    return BLE_ATT_ERR_READ_NOT_PERMITTED;
}

static int
gatt_svr_chr_access_csc_feature(uint16_t conn_handle, uint16_t attr_handle,
                                struct ble_gatt_access_ctxt *ctxt, void *arg)
{
    static const uint16_t csc_feature = CSC_FEATURES;
    int rc;

    assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR);
    rc = os_mbuf_append(ctxt->om, &csc_feature, sizeof(csc_feature));

    return (rc == 0) ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
}

static int
gatt_svr_chr_access_sensor_location(uint16_t conn_handle, uint16_t attr_handle,
                                  struct ble_gatt_access_ctxt *ctxt, void *arg)
{
    int rc;

    assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR);
    rc = os_mbuf_append(ctxt->om, &sensor_location, sizeof(sensor_location));

    return (rc == 0) ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
}

static int
gatt_svr_chr_access_sc_control_point(uint16_t conn_handle,
                                     uint16_t attr_handle,
                                     struct ble_gatt_access_ctxt *ctxt,
                                     void *arg)
{
    uint8_t op_code;
    uint8_t new_sensor_location;
    uint8_t new_cumulative_wheel_rev_arr[4];
    struct os_mbuf *om_indication;
    uint8_t response = SC_CP_RESPONSE_OP_NOT_SUPPORTED;
    int ii;
    int rc;

    assert(ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR);

    if (!csc_cp_indication_status) {
        MODLOG_DFLT(INFO, "SC Control Point; CCC descriptor "
                          "improperly configured");
        return CSC_ERR_CCC_DESC_IMPROPERLY_CONFIGURED;
    }

    /* Read control point op code*/
    rc = os_mbuf_copydata(ctxt->om, 0, sizeof(op_code), &op_code);
    if (rc != 0){
        return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
    }
    MODLOG_DFLT(INFO, "SC Control Point; opcode=%d\n", op_code);

    /* Allocate response buffer */
    om_indication = ble_hs_mbuf_att_pkt();

    switch(op_code){
#if (CSC_FEATURES & CSC_FEATURE_WHEEL_REV_DATA)
    case SC_CP_OP_SET_CUMULATIVE_VALUE:
        /* Read new cumulative wheel revolutions value*/
        rc = os_mbuf_copydata(ctxt->om, 1,
                              sizeof(new_cumulative_wheel_rev_arr),
                              new_cumulative_wheel_rev_arr);
        if (rc != 0){
            return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
        }

        measurement_state->cumulative_wheel_rev =
                           get_le32(new_cumulative_wheel_rev_arr);

        MODLOG_DFLT(INFO, "SC Control Point; Set cumulative value = %d\n",
                    measurement_state->cumulative_wheel_rev);

        response = SC_CP_RESPONSE_SUCCESS;
        break;
#endif

#if (CSC_FEATURES & CSC_FEATURE_MULTIPLE_SENSOR_LOC)
    case SC_CP_OP_UPDATE_SENSOR_LOCATION:
        /* Read new sensor location value*/
        rc = os_mbuf_copydata(ctxt->om, 1, 1, &new_sensor_location);
        if (rc != 0){
          return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
        }

        MODLOG_DFLT(INFO, "SC Control Point; Sensor location update = %d\n",
                    new_sensor_location);

        /* Verify if requested new location is on supported locations list */
        response = SC_CP_RESPONSE_INVALID_PARAM;
        for (ii = 0; ii < sizeof(csc_supported_sensor_locations); ii++){
            if (new_sensor_location == csc_supported_sensor_locations[ii]){
                sensor_location = new_sensor_location;
                response = SC_CP_RESPONSE_SUCCESS;
                break;
            }
        }
        break;

    case SC_CP_OP_REQ_SUPPORTED_SENSOR_LOCATIONS:
        response = SC_CP_RESPONSE_SUCCESS;
        break;
#endif

    default:
        break;
    }

    /* Append response value */
    rc = os_mbuf_append(om_indication, &response, sizeof(response));

    if (rc != 0){
      return BLE_ATT_ERR_INSUFFICIENT_RES;
    }

#if (CSC_FEATURES & CSC_FEATURE_MULTIPLE_SENSOR_LOC)
    /* In case of supported locations request append locations list */
    if (op_code == SC_CP_OP_REQ_SUPPORTED_SENSOR_LOCATIONS){
      rc = os_mbuf_append(om_indication, &csc_supported_sensor_locations,
                          sizeof(csc_supported_sensor_locations));
    }

    if (rc != 0){
      return BLE_ATT_ERR_INSUFFICIENT_RES;
    }
#endif

    rc = ble_gattc_indicate_custom(conn_handle, csc_control_point_handle,
                                   om_indication);

    return rc;
}

static int
gatt_svr_chr_access_device_info(uint16_t conn_handle, uint16_t attr_handle,
                                struct ble_gatt_access_ctxt *ctxt, void *arg)
{
    uint16_t uuid;
    int rc;

    uuid = ble_uuid_u16(ctxt->chr->uuid);

    if (uuid == GATT_MODEL_NUMBER_UUID) {
        rc = os_mbuf_append(ctxt->om, model_num, strlen(model_num));
        return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
    }

    if (uuid == GATT_MANUFACTURER_NAME_UUID) {
        rc = os_mbuf_append(ctxt->om, manuf_name, strlen(manuf_name));
        return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
    }

    assert(0);
    return BLE_ATT_ERR_UNLIKELY;
}

int
gatt_svr_chr_notify_csc_measurement(uint16_t conn_handle)
{
    int rc;
    struct os_mbuf *om;
    uint8_t data_buf[11];
    uint8_t data_offset = 1;

    memset(data_buf, 0, sizeof(data_buf));

#if (CSC_FEATURES & CSC_FEATURE_WHEEL_REV_DATA)
    data_buf[0] |= CSC_MEASUREMENT_WHEEL_REV_PRESENT;
    put_le16(&(data_buf[5]), measurement_state->last_wheel_evt_time);
    put_le32(&(data_buf[1]), measurement_state->cumulative_wheel_rev);
    data_offset += 6;
#endif

#if (CSC_FEATURES & CSC_FEATURE_CRANK_REV_DATA)
    data_buf[0] |= CSC_MEASUREMENT_CRANK_REV_PRESENT;
    put_le16(&(data_buf[data_offset]),
             measurement_state->cumulative_crank_rev);
    put_le16(&(data_buf[data_offset + 2]),
             measurement_state->last_crank_evt_time);
    data_offset += 4;
#endif

    om = ble_hs_mbuf_from_flat(data_buf, data_offset);

    rc = ble_gattc_notify_custom(conn_handle, csc_measurement_handle, om);
    return rc;
}

void
gatt_svr_set_cp_indicate(uint8_t indication_status)
{
  csc_cp_indication_status = indication_status;
}

void
gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg)
{
    char buf[BLE_UUID_STR_LEN];

    switch (ctxt->op) {
    case BLE_GATT_REGISTER_OP_SVC:
        MODLOG_DFLT(DEBUG, "registered service %s with handle=%d\n",
                    ble_uuid_to_str(ctxt->svc.svc_def->uuid, buf),
                    ctxt->svc.handle);
        break;

    case BLE_GATT_REGISTER_OP_CHR:
        MODLOG_DFLT(DEBUG, "registering characteristic %s with "
                           "def_handle=%d val_handle=%d\n",
                    ble_uuid_to_str(ctxt->chr.chr_def->uuid, buf),
                    ctxt->chr.def_handle,
                    ctxt->chr.val_handle);
        break;

    case BLE_GATT_REGISTER_OP_DSC:
        MODLOG_DFLT(DEBUG, "registering descriptor %s with handle=%d\n",
                    ble_uuid_to_str(ctxt->dsc.dsc_def->uuid, buf),
                    ctxt->dsc.handle);
        break;

    default:
        assert(0);
        break;
    }
}

int
gatt_svr_init(struct ble_csc_measurement_state * csc_measurement_state)
{
    int rc;

    rc = ble_gatts_count_cfg(gatt_svr_svcs);
    if (rc != 0) {
        return rc;
    }

    rc = ble_gatts_add_svcs(gatt_svr_svcs);
    if (rc != 0) {
        return rc;
    }

    measurement_state = csc_measurement_state;

    return 0;
}

