/*
 *
 *    Copyright (c) 2023 Project CHIP Authors
 *
 *    Licensed 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 "BLEAdvertisingArbiter.h"

#include <lib/support/CodeUtils.h>
#include <lib/support/logging/CHIPLogging.h>
#include <system/SystemError.h>

namespace chip {
namespace DeviceLayer {
namespace BLEAdvertisingArbiter {
namespace {

// List of advertising requests ordered by priority
sys_slist_t sRequests;

bool sIsInitialized = false;
uint8_t sBtId       = 0;

// Cast an intrusive list node to the containing request object
const BLEAdvertisingArbiter::Request & ToRequest(const sys_snode_t * node)
{
    return *static_cast<const BLEAdvertisingArbiter::Request *>(node);
}

// Notify application about stopped advertising if the callback has been provided
void NotifyAdvertisingStopped(const sys_snode_t * node)
{
    VerifyOrReturn(node);

    const Request & request = ToRequest(node);

    if (request.onStopped != nullptr)
    {
        request.onStopped();
    }
}

// Restart advertising using the top-priority request
CHIP_ERROR RestartAdvertising()
{
    // Note: bt_le_adv_stop() returns success when the advertising was not started
    ReturnErrorOnFailure(System::MapErrorZephyr(bt_le_adv_stop()));
    ReturnErrorCodeIf(sys_slist_is_empty(&sRequests), CHIP_NO_ERROR);

    const Request & top    = ToRequest(sys_slist_peek_head(&sRequests));
    bt_le_adv_param params = BT_LE_ADV_PARAM_INIT(top.options, top.minInterval, top.maxInterval, nullptr);
    params.id              = sBtId;
    const int result = bt_le_adv_start(&params, top.advertisingData.data(), top.advertisingData.size(), top.scanResponseData.data(),
                                       top.scanResponseData.size());

    if (top.onStarted != nullptr)
    {
        top.onStarted(result);
    }

    return System::MapErrorZephyr(result);
}

} // namespace

CHIP_ERROR Init(uint8_t btId)
{
    if (sIsInitialized)
    {
        return CHIP_ERROR_INCORRECT_STATE;
    }

    sBtId          = btId;
    sIsInitialized = true;

    return CHIP_NO_ERROR;
}

CHIP_ERROR InsertRequest(Request & request)
{
    if (!sIsInitialized)
    {
        return CHIP_ERROR_INCORRECT_STATE;
    }

    CancelRequest(request);

    sys_snode_t * prev = nullptr;
    sys_snode_t * node = nullptr;

    // Find position of the request in the list that preserves ordering by priority
    SYS_SLIST_FOR_EACH_NODE(&sRequests, node)
    {
        if (request.priority < ToRequest(node).priority)
        {
            break;
        }

        prev = node;
    }

    if (prev == nullptr)
    {
        NotifyAdvertisingStopped(sys_slist_peek_head(&sRequests));
        sys_slist_prepend(&sRequests, &request);
    }
    else
    {
        sys_slist_insert(&sRequests, prev, &request);
    }

    // If the request is top-priority, restart the advertising
    if (sys_slist_peek_head(&sRequests) == &request)
    {
        return RestartAdvertising();
    }

    return CHIP_NO_ERROR;
}

void CancelRequest(Request & request)
{
    if (!sIsInitialized)
    {
        return;
    }

    const bool isTopPriority = (sys_slist_peek_head(&sRequests) == &request);
    VerifyOrReturn(sys_slist_find_and_remove(&sRequests, &request));

    // If cancelled request was top-priority, restart the advertising.
    if (isTopPriority)
    {
        RestartAdvertising();
    }
}

} // namespace BLEAdvertisingArbiter
} // namespace DeviceLayer
} // namespace chip
