/*
 * 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 <stddef.h>
#include <string.h>
#include "host/ble_gatt.h"
#include "host/ble_uuid.h"
#include "console/console.h"
#include "nimble/ble.h"
#include "ble_hs_priv.h"

#if NIMBLE_BLE_CONNECT
static const ble_uuid_t *uuid_ccc =
        BLE_UUID16_DECLARE(BLE_GATT_DSC_CLT_CFG_UUID16);

static const char * const ble_gatt_chr_f_names[] = {
    "BROADCAST",
    "READ",
    "WRITE_NO_RSP",
    "WRITE",
    "NOTIFY",
    "INDICATE",
    "AUTH_SIGN_WRITE",
    "RELIABLE_WRITE",
    "AUX_WRITE",
    "READ_ENC",
    "READ_AUTHEN",
    "READ_AUTHOR",
    "WRITE_ENC",
    "WRITE_AUTHEN",
    "WRITE_AUTHOR",
    NULL
};

static const char * const ble_gatt_dsc_f_names[] = {
    "READ",
    "WRITE",
    "READ_ENC",
    "READ_AUTHEN",
    "READ_AUTHOR",
    "WRITE_ENC",
    "WRITE_AUTHEN",
    "WRITE_AUTHOR",
    NULL
};

#define BLE_CHR_FLAGS_STR_LEN 180

static char *
ble_gatts_flags_to_str(uint16_t flags, char *buf,
                       const char * const *names)
{
    int bit;
    bool non_empty = false;
    size_t length = 0;

    buf[0] = '\0';
    strcpy(buf, "[");
    length += 1;
    for (bit = 0; names[bit]; ++bit) {
        if (flags & (1 << bit)) {
            length += strlen(names[bit]);
            if (length + 1 >= BLE_CHR_FLAGS_STR_LEN) {
                return buf;
            }
            if (non_empty) {
                strcat(buf, "|");
                length += 1;
            }
            strcat(buf, names[bit]);
            non_empty = true;
        }
    }
    strcat(buf, "]");
    return buf;
}


#define STRINGIFY(X) #X
#define FIELD_NAME_LEN STRINGIFY(12)
#define FIELD_INDENT STRINGIFY(2)

static void
ble_gatt_show_local_chr(const struct ble_gatt_svc_def *svc,
                        uint16_t handle, char *uuid_buf, char *flags_buf)
{
    const struct ble_gatt_chr_def *chr;
    const struct ble_gatt_dsc_def *dsc;

    for (chr = svc->characteristics; chr && chr->uuid; ++chr) {
        console_printf("characteristic\n");
        console_printf("%" FIELD_INDENT "s %" FIELD_NAME_LEN "s "
                       "%s\n", " ", "uuid",
                       ble_uuid_to_str(chr->uuid, uuid_buf));
        console_printf("%" FIELD_INDENT "s %" FIELD_NAME_LEN "s "
                       "%d\n", " ", "def_handle", handle);
        console_printf("%" FIELD_INDENT "s %" FIELD_NAME_LEN "s "
                       "%d\n", " ", "val_handle", handle+1);
        console_printf("%" FIELD_INDENT "s %" FIELD_NAME_LEN "s "
                       "%d\n", " ", "min_key_size", chr->min_key_size);
        console_printf("%" FIELD_INDENT "s %" FIELD_NAME_LEN "s "
                       "%s\n", " ", "flags",
                       ble_gatts_flags_to_str(chr->flags,
                       flags_buf, ble_gatt_chr_f_names));
        handle += 2;

        if ((chr->flags & BLE_GATT_CHR_F_NOTIFY) ||
            (chr->flags & BLE_GATT_CHR_F_INDICATE)) {
            console_printf("ccc descriptor\n");
            console_printf("%" FIELD_INDENT "s %" FIELD_NAME_LEN "s "
                           "%s\n", " ", "uuid",
                           ble_uuid_to_str(uuid_ccc, uuid_buf));
            console_printf("%" FIELD_INDENT "s %" FIELD_NAME_LEN "s "
                           "%d\n", " ", "handle", handle);
            console_printf("%" FIELD_INDENT "s %" FIELD_NAME_LEN "s "
                           "%d\n", " ", "min_key_size", 0);
            console_printf("%" FIELD_INDENT "s %" FIELD_NAME_LEN "s "
                           "%s\n", " ", "flags",
                           ble_gatts_flags_to_str(BLE_ATT_F_READ | BLE_ATT_F_WRITE,
                                                  flags_buf, ble_gatt_dsc_f_names));
            handle++;
        }

        for (dsc = chr->descriptors; dsc && dsc->uuid; ++dsc) {
            console_printf("descriptor\n");
            console_printf("%" FIELD_INDENT "s %" FIELD_NAME_LEN "s "
                           "%s\n", " ", "uuid",
                           ble_uuid_to_str(dsc->uuid, uuid_buf));
            console_printf("%" FIELD_INDENT "s %" FIELD_NAME_LEN "s "
                           "%d\n", " ", "handle", handle);
            console_printf("%" FIELD_INDENT "s %" FIELD_NAME_LEN "s "
                           "%d\n", " ", "min_key_size", dsc->min_key_size);
            console_printf("%" FIELD_INDENT "s %" FIELD_NAME_LEN "s "
                           "%s\n", " ", "flags",
                           ble_gatts_flags_to_str(dsc->att_flags,
                           flags_buf, ble_gatt_dsc_f_names));
            handle++;
        }
    }
}

static int
ble_gatt_show_local_inc_svc(const struct ble_gatt_svc_def *svc,
                            uint16_t handle, char *uuid_buf)
{
    const struct ble_gatt_svc_def **includes;
    int num = 0;

    for (includes = &svc->includes[0]; *includes != NULL; ++includes) {
        console_printf("included service\n");
        console_printf("%" FIELD_INDENT "s %" FIELD_NAME_LEN "s "
                       "%s\n", " ", "uuid",
                       ble_uuid_to_str((*includes)->uuid, uuid_buf));
        console_printf("%" FIELD_INDENT "s %" FIELD_NAME_LEN "s "
                       "%d\n", " ", "attr handle", handle);
        ++num;
    }

    return num;
}

static void
ble_gatt_show_local_svc(const struct ble_gatt_svc_def *svc,
                        uint16_t handle, uint16_t end_group_handle,
                        void *arg)
{
    char uuid_buf[BLE_UUID_STR_LEN];
    char flags_buf[BLE_CHR_FLAGS_STR_LEN];

    console_printf("%s service\n",
                   svc->type == BLE_GATT_SVC_TYPE_PRIMARY ?
                           "primary" : "secondary");
    console_printf("%" FIELD_INDENT "s %" FIELD_NAME_LEN "s "
                   "%s\n", " ", "uuid",
                   ble_uuid_to_str(svc->uuid, uuid_buf));
    console_printf("%" FIELD_INDENT "s %" FIELD_NAME_LEN "s "
                   "%d\n", " ", "handle",
                   handle);
    console_printf("%" FIELD_INDENT "s %" FIELD_NAME_LEN "s "
                   "%d\n", " ", "end_handle",
                   end_group_handle);
    handle++;

    if (svc->includes) {
        handle += ble_gatt_show_local_inc_svc(svc, handle, uuid_buf);
    }

    ble_gatt_show_local_chr(svc, handle,
                            uuid_buf, flags_buf);
}

void
ble_gatts_show_local(void)
{
    ble_gatts_lcl_svc_foreach(ble_gatt_show_local_svc, NULL);
}

#endif
