/*
 * 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 "testutil/testutil.h"
#include "host/ble_hs_test.h"
#include "ble_hs_test_util.h"

static struct ble_store_status_event ble_store_test_status_event;

static void
ble_store_test_util_verify_peer_deleted(const ble_addr_t *addr)
{
    union ble_store_value value;
    union ble_store_key key;
    ble_addr_t addrs[64];
    int num_addrs;
    int rc;
    int i;

    memset(&key, 0, sizeof key);
    key.sec.peer_addr = *addr;
    rc = ble_store_read(BLE_STORE_OBJ_TYPE_OUR_SEC, &key, &value);
    TEST_ASSERT(rc == BLE_HS_ENOENT);
    rc = ble_store_read(BLE_STORE_OBJ_TYPE_PEER_SEC, &key, &value);
    TEST_ASSERT(rc == BLE_HS_ENOENT);

    memset(&key, 0, sizeof key);
    key.cccd.peer_addr = *addr;
    rc = ble_store_read(BLE_STORE_OBJ_TYPE_CCCD, &key, &value);
    TEST_ASSERT(rc == BLE_HS_ENOENT);

    rc = ble_store_util_bonded_peers(addrs, &num_addrs,
                                     sizeof addrs / sizeof addrs[0]);
    TEST_ASSERT_FATAL(rc == 0);
    for (i = 0; i < num_addrs; i++) {
        TEST_ASSERT(ble_addr_cmp(addr, addrs + i) != 0);
    }
}

static int
ble_store_test_util_status_overflow(struct ble_store_status_event *event,
                                    void *arg)
{
    int *status;

    status = arg;

    ble_store_test_status_event = *event;
    return *status;
}

static void
ble_store_test_util_overflow_sec(int is_our_sec)
{
    union ble_store_value val;
    int obj_type;
    int status;
    int rc;
    int i;

    ble_hs_test_util_init();

    ble_hs_cfg.store_status_cb = ble_store_test_util_status_overflow;
    ble_hs_cfg.store_status_arg = &status;

    if (is_our_sec) {
        obj_type = BLE_STORE_OBJ_TYPE_OUR_SEC;
    } else {
        obj_type = BLE_STORE_OBJ_TYPE_PEER_SEC;
    }

    memset(&ble_store_test_status_event, 0,
           sizeof ble_store_test_status_event);
    memset(&val, 0, sizeof val);

    val.sec.peer_addr =
        (ble_addr_t){ BLE_ADDR_PUBLIC, { 1, 2, 3, 4, 5, 6 } };
    val.sec.ltk_present = 1,

    status = BLE_HS_ESTORE_CAP;
    for (i = 0; ; i++) {
        rc = ble_store_write(obj_type, &val);
        if (i < MYNEWT_VAL(BLE_STORE_MAX_BONDS)) {
            TEST_ASSERT_FATAL(rc == 0);
        } else {
            /* This record should have caused an overflow. */
            TEST_ASSERT(rc == BLE_HS_ESTORE_CAP);
            TEST_ASSERT(ble_store_test_status_event.event_code ==
                        BLE_STORE_EVENT_OVERFLOW);
            TEST_ASSERT(ble_store_test_status_event.overflow.obj_type ==
                        obj_type);
            TEST_ASSERT(ble_store_test_status_event.overflow.value == &val);
            break;
        }

        val.sec.peer_addr.val[0]++;
    }
}

static int
ble_store_test_util_count(int obj_type)
{
    int count;
    int rc;

    rc = ble_store_util_count(obj_type, &count);
    TEST_ASSERT_FATAL(rc == 0);

    return count;
}

TEST_CASE(ble_store_test_peers)
{
    struct ble_store_value_sec secs[3] = {
        {
            .peer_addr = { BLE_ADDR_PUBLIC,     { 1, 2, 3, 4, 5, 6 } },
            .ltk_present = 1,
        },
        {
            /* Address value is a duplicate of above, but type differs. */
            .peer_addr = { BLE_ADDR_RANDOM,     { 1, 2, 3, 4, 5, 6 } },
            .ltk_present = 1,
        },
        {
            .peer_addr = { BLE_ADDR_PUBLIC,     { 2, 3, 4, 5, 6, 7 } },
            .ltk_present = 1,
        },
    };
    ble_addr_t peer_addrs[3];
    int num_addrs;
    int rc;
    int i;

    ble_hs_test_util_init();

    for (i = 0; i < sizeof secs / sizeof secs[0]; i++) {
        rc = ble_store_write_our_sec(secs + i);
        TEST_ASSERT_FATAL(rc == 0);
        rc = ble_store_write_peer_sec(secs + i);
        TEST_ASSERT_FATAL(rc == 0);
    }

    rc = ble_store_util_bonded_peers(peer_addrs, &num_addrs,
                                     sizeof peer_addrs / sizeof peer_addrs[0]);
    TEST_ASSERT_FATAL(rc == 0);

    TEST_ASSERT(num_addrs == sizeof secs / sizeof secs[0]);
    for (i = 0; i < num_addrs; i++) {
        TEST_ASSERT(ble_addr_cmp(&peer_addrs[i], &secs[i].peer_addr) == 0);
    }
}

TEST_CASE(ble_store_test_delete_peer)
{
    struct ble_store_value_sec secs[2] = {
        {
            .peer_addr = { BLE_ADDR_PUBLIC,     { 1, 2, 3, 4, 5, 6 } },
            .ltk_present = 1,
        },
        {
            /* Address value is a duplicate of above, but type differs. */
            .peer_addr = { BLE_ADDR_RANDOM,     { 1, 2, 3, 4, 5, 6 } },
            .ltk_present = 1,
        },
    };
    struct ble_store_value_cccd cccds[3] = {
        /* First two belong to first peer. */
        {
            .peer_addr = secs[0].peer_addr,
            .chr_val_handle = 5,
        },
        {
            .peer_addr = secs[0].peer_addr,
            .chr_val_handle = 8,
        },

        /* Last belongs to second peer. */
        {
            .peer_addr = secs[1].peer_addr,
            .chr_val_handle = 5,
        },
    };
    union ble_store_value value;
    union ble_store_key key;
    int count;
    int rc;
    int i;

    ble_hs_test_util_init();

    for (i = 0; i < sizeof secs / sizeof secs[0]; i++) {
        rc = ble_store_write_our_sec(secs + i);
        TEST_ASSERT_FATAL(rc == 0);
        rc = ble_store_write_peer_sec(secs + i);
        TEST_ASSERT_FATAL(rc == 0);
    }

    for (i = 0; i < sizeof cccds / sizeof cccds[0]; i++) {
        rc = ble_store_write_cccd(cccds + i);
        TEST_ASSERT_FATAL(rc == 0);
    }

    /* Delete first peer. */
    rc = ble_store_util_delete_peer(&secs[0].peer_addr);
    TEST_ASSERT_FATAL(rc == 0);

    /* Ensure all traces of first peer have been removed. */
    ble_store_test_util_verify_peer_deleted(&secs[0].peer_addr);

    /* Ensure second peer data is still intact. */
    ble_store_key_from_value_sec(&key.sec, secs + 1);

    rc = ble_store_util_count(BLE_STORE_OBJ_TYPE_OUR_SEC, &count);
    TEST_ASSERT_FATAL(rc == 0);
    TEST_ASSERT(count == 1);

    rc = ble_store_read_our_sec(&key.sec, &value.sec);
    TEST_ASSERT_FATAL(rc == 0);
    TEST_ASSERT(memcmp(&value.sec, secs + 1, sizeof value.sec) == 0);

    rc = ble_store_util_count(BLE_STORE_OBJ_TYPE_PEER_SEC, &count);
    TEST_ASSERT_FATAL(rc == 0);
    TEST_ASSERT(count == 1);

    rc = ble_store_read_peer_sec(&key.sec, &value.sec);
    TEST_ASSERT_FATAL(rc == 0);
    TEST_ASSERT(memcmp(&value.sec, secs + 1, sizeof value.sec) == 0);

    ble_store_key_from_value_cccd(&key.cccd, cccds + 2);

    rc = ble_store_util_count(BLE_STORE_OBJ_TYPE_CCCD, &count);
    TEST_ASSERT_FATAL(rc == 0);
    TEST_ASSERT(count == 1);

    rc = ble_store_read_cccd(&key.cccd, &value.cccd);
    TEST_ASSERT_FATAL(rc == 0);
    TEST_ASSERT(memcmp(&value.cccd, cccds + 2, sizeof value.cccd) == 0);

    /* Delete second peer. */
    rc = ble_store_util_delete_peer(&secs[1].peer_addr);
    TEST_ASSERT_FATAL(rc == 0);

    /* Ensure all traces of first peer have been removed. */
    ble_store_test_util_verify_peer_deleted(&secs[1].peer_addr);
}

TEST_CASE(ble_store_test_count)
{
    struct ble_store_value_sec secs[4] = {
        {
            .peer_addr = { BLE_ADDR_PUBLIC,     { 1, 2, 3, 4, 5, 6 } },
            .ltk_present = 1,
        },
        {
            .peer_addr = { BLE_ADDR_RANDOM,     { 1, 2, 3, 4, 5, 6 } },
            .ltk_present = 1,
        },
        {
            .peer_addr = { BLE_ADDR_PUBLIC,     { 2, 3, 4, 5, 6, 7 } },
            .ltk_present = 1,
        },
        {
            .peer_addr = { BLE_ADDR_RANDOM,     { 3, 4, 5, 6, 7, 8 } },
            .ltk_present = 1,
        },
    };
    struct ble_store_value_cccd cccds[2] = {
        {
            .peer_addr = secs[0].peer_addr,
            .chr_val_handle = 5,
        },
        {
            .peer_addr = secs[0].peer_addr,
            .chr_val_handle = 8,
        },
    };
    int count;
    int rc;
    int i;

    ble_hs_test_util_init();

    /*** Verify initial counts are 0. */

    rc = ble_store_util_count(BLE_STORE_OBJ_TYPE_OUR_SEC, &count);
    TEST_ASSERT_FATAL(rc == 0);
    TEST_ASSERT(count == 0);

    rc = ble_store_util_count(BLE_STORE_OBJ_TYPE_PEER_SEC, &count);
    TEST_ASSERT_FATAL(rc == 0);
    TEST_ASSERT(count == 0);

    rc = ble_store_util_count(BLE_STORE_OBJ_TYPE_CCCD, &count);
    TEST_ASSERT_FATAL(rc == 0);
    TEST_ASSERT(count == 0);

    /* Write some test data. */

    for (i = 0; i < 3; i++) {
        rc = ble_store_write_our_sec(secs + i);
        TEST_ASSERT_FATAL(rc == 0);
    }
    for (i = 0; i < 2; i++) {
        rc = ble_store_write_peer_sec(secs + i);
        TEST_ASSERT_FATAL(rc == 0);
    }
    for (i = 0; i < 1; i++) {
        rc = ble_store_write_cccd(cccds + i);
        TEST_ASSERT_FATAL(rc == 0);
    }

    /*** Verify counts after populating store. */
    rc = ble_store_util_count(BLE_STORE_OBJ_TYPE_OUR_SEC, &count);
    TEST_ASSERT_FATAL(rc == 0);
    TEST_ASSERT(count == 3);

    rc = ble_store_util_count(BLE_STORE_OBJ_TYPE_PEER_SEC, &count);
    TEST_ASSERT_FATAL(rc == 0);
    TEST_ASSERT(count == 2);

    rc = ble_store_util_count(BLE_STORE_OBJ_TYPE_CCCD, &count);
    TEST_ASSERT_FATAL(rc == 0);
    TEST_ASSERT(count == 1);
}

TEST_CASE(ble_store_test_overflow)
{
    ble_store_test_util_overflow_sec(0);
    ble_store_test_util_overflow_sec(1);
}

TEST_CASE(ble_store_test_clear)
{
    const struct ble_store_value_sec secs[2] = {
        {
            .peer_addr = { BLE_ADDR_PUBLIC,     { 1, 2, 3, 4, 5, 6 } },
            .ltk_present = 1,
        },
        {
            /* Address value is a duplicate of above, but type differs. */
            .peer_addr = { BLE_ADDR_RANDOM,     { 1, 2, 3, 4, 5, 6 } },
            .ltk_present = 1,
        },
    };
    const struct ble_store_value_cccd cccds[3] = {
        /* First two belong to first peer. */
        {
            .peer_addr = secs[0].peer_addr,
            .chr_val_handle = 5,
        },
        {
            .peer_addr = secs[0].peer_addr,
            .chr_val_handle = 8,
        },

        /* Last belongs to second peer. */
        {
            .peer_addr = secs[1].peer_addr,
            .chr_val_handle = 5,
        },
    };
    int rc;
    int i;

    ble_hs_test_util_init();

    for (i = 0; i < sizeof secs / sizeof secs[0]; i++) {
        rc = ble_store_write_our_sec(secs + i);
        TEST_ASSERT_FATAL(rc == 0);
        rc = ble_store_write_peer_sec(secs + i);
        TEST_ASSERT_FATAL(rc == 0);
    }

    for (i = 0; i < sizeof cccds / sizeof cccds[0]; i++) {
        rc = ble_store_write_cccd(cccds + i);
        TEST_ASSERT_FATAL(rc == 0);
    }

    /* Sanity check. */
    TEST_ASSERT_FATAL(
        ble_store_test_util_count(BLE_STORE_OBJ_TYPE_OUR_SEC) == 2);
    TEST_ASSERT_FATAL(
        ble_store_test_util_count(BLE_STORE_OBJ_TYPE_PEER_SEC) == 2);
    TEST_ASSERT_FATAL(
        ble_store_test_util_count(BLE_STORE_OBJ_TYPE_CCCD) == 3);

    /* Ensure store is empty after clear gets called. */
    rc = ble_store_clear();
    TEST_ASSERT_FATAL(rc == 0);
    TEST_ASSERT(ble_store_test_util_count(BLE_STORE_OBJ_TYPE_OUR_SEC) == 0);
    TEST_ASSERT(ble_store_test_util_count(BLE_STORE_OBJ_TYPE_PEER_SEC) == 0);
    TEST_ASSERT(ble_store_test_util_count(BLE_STORE_OBJ_TYPE_CCCD) == 0);

    /* Ensure second clear succeeds with no effect. */
    rc = ble_store_clear();
    TEST_ASSERT_FATAL(rc == 0);
    TEST_ASSERT(ble_store_test_util_count(BLE_STORE_OBJ_TYPE_OUR_SEC) == 0);
    TEST_ASSERT(ble_store_test_util_count(BLE_STORE_OBJ_TYPE_PEER_SEC) == 0);
    TEST_ASSERT(ble_store_test_util_count(BLE_STORE_OBJ_TYPE_CCCD) == 0);
}

TEST_SUITE(ble_store_suite)
{
    tu_suite_set_post_test_cb(ble_hs_test_util_post_test, NULL);

    ble_store_test_peers();
    ble_store_test_delete_peer();
    ble_store_test_count();
    ble_store_test_overflow();
    ble_store_test_clear();
}

int
ble_store_test_all(void)
{
    ble_store_suite();

    return tu_any_failed;
}
