/*
 *
 *    Copyright (c) 2024 Project CHIP Authors
 *    All rights reserved.
 *
 *    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 <gtest/gtest.h>

#include <lib/core/GroupedCallbackList.h>
#include <lib/support/logging/CHIPLogging.h>

#include <unordered_map>

using namespace chip::Callback;

// Expose Cancelable anchor for testing
template <typename... T>
struct TestGroupedCallbackList : public GroupedCallbackList<T...>
{
    Cancelable * Anchor() { return this; }
};

static void CallbackFn(void *) {}
static void CallbackWithIntFn(void *, int) {}

typedef void (*CallWithIntFn)(void *, int);

static void * StringContext(char const * string)
{
    return const_cast<void *>(static_cast<void const *>(string));
}

static void ValidateList(Cancelable const * anchor)
{
#if 0 // for manual debugging
    {
        ChipLogDetail(NotSpecified, "ANCHOR: %p", anchor);
        Cancelable * ca = anchor->mNext;
        while (ca != anchor)
        {
            auto * cb = Callback<>::FromCancelable(ca);
            ChipLogDetail(NotSpecified, "%s%p (prev=%p, cancel=%p) %s", (ca->mPrev->mNext == ca) ? "> " : "  ", ca, ca->mPrev,
                          ca->mCancel, static_cast<char const *>(cb->mContext));
            ca = ca->mNext;
        }
    }
#endif
    {
        EXPECT_TRUE(anchor->mPrev->mNext == anchor);
        EXPECT_TRUE(anchor->mNext->mPrev == anchor);

        std::unordered_map<Cancelable const *, size_t> index;
        index[anchor] = 0;

        size_t lastPrevIndex = 0;
        Cancelable * ca      = anchor->mNext;
        for (size_t i = 1; ca != anchor; i++, ca = ca->mNext)
        {
            EXPECT_TRUE(index.find(ca) == index.end()); // cycle?
            index[ca] = i;

            Cancelable * prev = ca->mPrev;
            auto search       = index.find(prev);
            EXPECT_TRUE(search != index.end());       // prev should point backwards
            EXPECT_GE(search->second, lastPrevIndex); // should be monotonic
            lastPrevIndex = search->second;
        }
    }
}

TEST(GroupedCallbackListTest, Trivial)
{
    TestGroupedCallbackList<CallFn> list;
    Callback<> * out = nullptr;
    EXPECT_TRUE(list.IsEmpty());
    EXPECT_FALSE(list.Peek(out));

    Callback cbOne(CallbackFn, StringContext("cbOne"));
    list.Enqueue(&cbOne);
    EXPECT_FALSE(list.IsEmpty());
    EXPECT_TRUE(list.Peek(out));
    EXPECT_TRUE(out == &cbOne);

    cbOne.Cancel();
    EXPECT_TRUE(list.IsEmpty());
}

TEST(GroupedCallbackListTest, EnqueueAllAndPeek)
{
    TestGroupedCallbackList<CallFn, CallWithIntFn> list;
    Callback cbOne(CallbackFn, StringContext("cbOne"));
    Callback cbTwo(CallbackWithIntFn, StringContext("cbTwo"));
    list.Enqueue(&cbOne, &cbTwo);
    ValidateList(list.Anchor());
    Callback<CallFn> * outOne        = nullptr;
    Callback<CallWithIntFn> * outTwo = nullptr;
    EXPECT_TRUE(list.Peek(outOne, outTwo));
    EXPECT_TRUE(outOne == &cbOne);
    EXPECT_TRUE(outTwo == &cbTwo);
}

TEST(GroupedCallbackListTest, EnqueueSparseAndPeek)
{
    TestGroupedCallbackList<CallFn, CallFn> list;
    Callback cbTwo(CallbackFn, StringContext("cbTwo"));
    list.Enqueue(nullptr, &cbTwo);
    ValidateList(list.Anchor());
    Callback<> * outOne = &cbTwo; // poison
    Callback<> * outTwo = nullptr;
    EXPECT_TRUE(list.Peek(outOne, outTwo));
    EXPECT_TRUE(outOne == nullptr);
    EXPECT_TRUE(outTwo == &cbTwo);
}

TEST(GroupedCallbackListTest, EnqueueAndClear)
{
    TestGroupedCallbackList<CallFn, CallWithIntFn> list;
    Callback cbOne(CallbackFn, StringContext("cbOne"));
    Callback cbTwo(CallbackWithIntFn, StringContext("cbTwo"));
    list.Enqueue(&cbOne, &cbTwo);
    Callback cbThree(CallbackFn, StringContext("cbThree"));
    list.Enqueue(&cbThree, nullptr);
    ValidateList(list.Anchor());
    EXPECT_FALSE(list.IsEmpty());
    EXPECT_TRUE(cbOne.IsRegistered());
    EXPECT_TRUE(cbTwo.IsRegistered());
    EXPECT_TRUE(cbThree.IsRegistered());

    list.Clear();
    ValidateList(list.Anchor());
    EXPECT_TRUE(list.IsEmpty());
    EXPECT_FALSE(cbOne.IsRegistered());
    EXPECT_FALSE(cbTwo.IsRegistered());
    EXPECT_FALSE(cbThree.IsRegistered());
}

TEST(GroupedCallbackListTest, Complex)
{
    TestGroupedCallbackList<CallFn, CallFn> list;
    ValidateList(list.Anchor());
    EXPECT_TRUE(list.IsEmpty());

    Callback cbZero(CallbackFn, StringContext("cbZero"));
    list.Enqueue(&cbZero, nullptr);
    ValidateList(list.Anchor());
    EXPECT_FALSE(list.IsEmpty());
    EXPECT_TRUE(cbZero.IsRegistered());

    Callback cbOne(CallbackFn, StringContext("cbOne"));
    Callback cbTwo(CallbackFn, StringContext("cbTwo"));
    list.Enqueue(&cbOne, &cbTwo);
    ValidateList(list.Anchor());
    EXPECT_TRUE(cbOne.IsRegistered());
    EXPECT_TRUE(cbTwo.IsRegistered());

    cbZero.Cancel();
    ValidateList(list.Anchor());
    EXPECT_FALSE(cbZero.IsRegistered());

    Callback cbThree(CallbackFn, StringContext("cbThree"));
    list.Enqueue(&cbThree, nullptr);
    ValidateList(list.Anchor());

    Callback cbFour(CallbackFn, StringContext("cbFour"));
    list.Enqueue(nullptr, &cbFour);
    ValidateList(list.Anchor());

    cbOne.Cancel(); // also cancels cbTwo
    ValidateList(list.Anchor());
    EXPECT_FALSE(cbOne.IsRegistered());
    EXPECT_FALSE(cbTwo.IsRegistered());

    Callback<> * outA = &cbZero;
    Callback<> * outB = &cbZero;
    EXPECT_TRUE(list.Take(outA, outB));
    ValidateList(list.Anchor());
    EXPECT_TRUE(outA == &cbThree);
    EXPECT_TRUE(outB == nullptr);

    EXPECT_TRUE(list.Take(outA, outB));
    ValidateList(list.Anchor());
    EXPECT_TRUE(outA == nullptr);
    EXPECT_TRUE(outB == &cbFour);

    EXPECT_TRUE(list.IsEmpty());
}

TEST(GroupedCallbackListTest, EnqueueTakeAll)
{
    TestGroupedCallbackList<CallFn, CallFn> listA;
    Callback cbOne(CallbackFn, StringContext("cbOne"));
    Callback cbTwo(CallbackFn, StringContext("cbTwo"));
    listA.Enqueue(&cbOne, &cbTwo);
    ValidateList(listA.Anchor());
    EXPECT_FALSE(listA.IsEmpty());
    EXPECT_TRUE(cbOne.IsRegistered());
    EXPECT_TRUE(cbTwo.IsRegistered());

    TestGroupedCallbackList<CallFn, CallFn> listB;
    Callback cbThree(CallbackFn, StringContext("cbThree"));
    listB.Enqueue(&cbThree, nullptr);
    ValidateList(listB.Anchor());
    EXPECT_FALSE(listB.IsEmpty());
    EXPECT_TRUE(cbThree.IsRegistered());

    listB.EnqueueTakeAll(listA);
    ValidateList(listA.Anchor());
    ValidateList(listB.Anchor());
    EXPECT_TRUE(cbThree.IsRegistered());
    EXPECT_TRUE(cbOne.IsRegistered());
    EXPECT_TRUE(cbTwo.IsRegistered());
    EXPECT_FALSE(listB.IsEmpty());
    EXPECT_TRUE(listA.IsEmpty());
}
