/*
 *
 *    Copyright (c) 2020 Project CHIP Authors
 *    Copyright (c) 2016-2017 Nest Labs, Inc.
 *
 *    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.
 */

/**
 * @file
 *  This file implements the CHIP API to collect statistics
 *  on the state of CHIP, Inet and System resources
 */

// Include local headers
#include <system/SystemTimer.h>

// Include module header
#include <system/SystemStats.h>

#include <lib/support/SafeInt.h>
#include <platform/LockTracker.h>

#include <string.h>

namespace chip {
namespace System {
namespace Stats {

static const Label sStatsStrings[chip::System::Stats::kNumEntries] = {
#if CHIP_SYSTEM_CONFIG_USE_LWIP && LWIP_PBUF_FROM_CUSTOM_POOLS
#define LWIP_PBUF_MEMPOOL(name, num, payload, desc) "SystemLayer_Num" desc,
#include "lwippools.h"
#undef LWIP_PBUF_MEMPOOL
#else
    "SystemLayer_NumPacketBufs",
#endif
    "SystemLayer_NumTimersInUse",
#if INET_CONFIG_NUM_TCP_ENDPOINTS
    "InetLayer_NumTCPEpsInUse",
#endif
#if INET_CONFIG_NUM_UDP_ENDPOINTS
    "InetLayer_NumUDPEpsInUse",
#endif
    "ExchangeMgr_NumContextsInUse", "ExchangeMgr_NumUMHandlersInUse", "ExchangeMgr_NumBindings", "MessageLayer_NumConnectionsInUse",
};

count_t sResourcesInUse[kNumEntries];
count_t sHighWatermarks[kNumEntries];

const Label * GetStrings()
{
    return sStatsStrings;
}

count_t * GetResourcesInUse()
{
    return sResourcesInUse;
}

count_t * GetHighWatermarks()
{
    return sHighWatermarks;
}

void UpdateSnapshot(Snapshot & aSnapshot)
{
    memcpy(&aSnapshot.mResourcesInUse, &sResourcesInUse, sizeof(aSnapshot.mResourcesInUse));
    memcpy(&aSnapshot.mHighWatermarks, &sHighWatermarks, sizeof(aSnapshot.mHighWatermarks));

#if CHIP_SYSTEM_CONFIG_USE_TIMER_POOL
    chip::System::Timer::GetStatistics(aSnapshot.mResourcesInUse[kSystemLayer_NumTimers],
                                       aSnapshot.mHighWatermarks[kSystemLayer_NumTimers]);
#endif // CHIP_SYSTEM_CONFIG_USE_TIMER_POOL

    SYSTEM_STATS_UPDATE_LWIP_PBUF_COUNTS();
}

bool Difference(Snapshot & result, Snapshot & after, Snapshot & before)
{
    int i;
    bool leak = false;

    for (i = 0; i < kNumEntries; i++)
    {
        // TODO: These casts can be bogus.  https://github.com/project-chip/connectedhomeip/issues/2949
        result.mResourcesInUse[i] = static_cast<count_t>(after.mResourcesInUse[i] - before.mResourcesInUse[i]);
        result.mHighWatermarks[i] = static_cast<count_t>(after.mHighWatermarks[i] - before.mHighWatermarks[i]);

        if (result.mResourcesInUse[i] > 0)
        {
            leak = true;
        }
    }

    return leak;
}

#if CHIP_SYSTEM_CONFIG_USE_LWIP && LWIP_STATS && MEMP_STATS

void UpdateLwipPbufCounts(void)
{
#if LWIP_PBUF_FROM_CUSTOM_POOLS
    size_t lwip_pool_idx = PBUF_CUSTOM_POOL_IDX_END;
    size_t system_idx    = 0;

    while (lwip_pool_idx <= PBUF_CUSTOM_POOL_IDX_START)
    {
        chip::System::Stats::GetResourcesInUse()[system_idx] = MEMP_STATS_GET(used, lwip_pool_idx);
        chip::System::Stats::GetHighWatermarks()[system_idx] = MEMP_STATS_GET(max, lwip_pool_idx);
        lwip_pool_idx++;
        system_idx++;
    }

#else // LWIP_PBUF_FROM_CUSTOM_POOLS

    chip::System::Stats::GetResourcesInUse()[kSystemLayer_NumPacketBufs] = MEMP_STATS_GET(used, MEMP_PBUF_POOL);
    chip::System::Stats::GetHighWatermarks()[kSystemLayer_NumPacketBufs] = MEMP_STATS_GET(max, MEMP_PBUF_POOL);

#endif // LWIP_PBUF_FROM_CUSTOM_POOLS
}
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP && LWIP_STATS && MEMP_STATS

} // namespace Stats
} // namespace System
} // namespace chip
