/*
 *
 *    Copyright (c) 2021 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/dnssd/Advertiser_ImplMinimalMdnsAllocator.h>

using namespace chip;
using namespace chip::Dnssd;
using namespace mdns::Minimal;

#if CHIP_CONFIG_MEMORY_DEBUG_DMALLOC
#include <dmalloc.h>
#endif // CHIP_CONFIG_MEMORY_DEBUG_DMALLOC

namespace {

constexpr size_t kMaxRecords = 10;
class TestAllocator : public QueryResponderAllocator<kMaxRecords>
{
public:
    TestAllocator()
    {
#if CHIP_CONFIG_MEMORY_DEBUG_DMALLOC
        // void dmalloc_track(const dmalloc_track_t track_func)
#endif
    }
    void TestAllQNamesAreNull()
    {
        for (size_t i = 0; i < GetMaxAllocatedQNames(); ++i)
        {
            EXPECT_EQ(GetQNamePart(i), nullptr);
        }
    }
    void TestAllRecordRespondersAreNull()
    {
        for (size_t i = 0; i < kMaxRecords; ++i)
        {
            EXPECT_EQ(GetRecordResponder(i), nullptr);
        }
    }
    void TestRecordRespondersMatchQuery()
    {
        mdns::Minimal::QueryResponderRecordFilter noFilter;
        auto queryResponder = GetQueryResponder();
        size_t idx          = 0;
        for (auto it = queryResponder->begin(&noFilter); it != queryResponder->end(); it++, idx++)
        {
            // TODO: Once the responders are exposed in the query responder, check that they match.
            EXPECT_LT(idx, kMaxRecords);
        }
    }
    size_t GetMaxAllocatedQNames() { return QueryResponderAllocator<kMaxRecords>::GetMaxAllocatedQNames(); }
};

class TestMinimalMdnsAllocator : public ::testing::Test
{
public:
    static void SetUpTestSuite() { ASSERT_EQ(chip::Platform::MemoryInit(), CHIP_NO_ERROR); }
    static void TearDownTestSuite() { chip::Platform::MemoryShutdown(); }
};

TEST_F(TestMinimalMdnsAllocator, TestQueryAllocatorQName)
{
    TestAllocator test;
#if CHIP_CONFIG_MEMORY_DEBUG_DMALLOC
    unsigned long mark = dmalloc_mark();
#endif
    // Start empty.
    test.TestAllRecordRespondersAreNull();
    test.TestAllQNamesAreNull();

    // We should be able to add up to GetMaxAllocatedQNames QNames
    for (size_t i = 0; i < test.GetMaxAllocatedQNames(); ++i)
    {
        EXPECT_NE(test.AllocateQName("test", "testy", "udp"), FullQName());
        test.TestAllRecordRespondersAreNull();
    }

#if CHIP_CONFIG_MEMORY_DEBUG_DMALLOC
    // Count the memory that has not been freed at this point (since mark)
    unsigned long nAllocated = dmalloc_count_changed(mark, 1, 0);
    EXPECT_NE(nAllocated, 0);
#endif

    // Adding one more should fail.
    EXPECT_EQ(test.AllocateQName("test", "testy", "udp"), FullQName());
    test.TestAllRecordRespondersAreNull();

#if CHIP_CONFIG_MEMORY_DEBUG_DMALLOC
    // We should not have allocated any more memory
    EXPECT_EQ(nAllocated, dmalloc_count_changed(mark, 1, 0));
#endif

    // Clear should take us back to all empty.
    test.Clear();
    test.TestAllQNamesAreNull();
    test.TestAllRecordRespondersAreNull();

#if CHIP_CONFIG_MEMORY_DEBUG_DMALLOC
    // The amount of unfreed pointers should be 0.
    EXPECT_EQ(dmalloc_count_changed(mark, 1, 0), 0);
#endif
}

TEST_F(TestMinimalMdnsAllocator, TestQueryAllocatorQNameArray)
{
    TestAllocator test;

#if CHIP_CONFIG_MEMORY_DEBUG_DMALLOC
    unsigned long mark = dmalloc_mark();
#endif

    constexpr size_t kNumParts     = 4;
    const char * kArray[kNumParts] = { "this", "is", "a", "test" };

    // Start empty.
    test.TestAllRecordRespondersAreNull();
    test.TestAllQNamesAreNull();

    // We should be able to add up to GetMaxAllocatedQNames QNames
    for (size_t i = 0; i < test.GetMaxAllocatedQNames(); ++i)
    {
        EXPECT_NE(test.AllocateQNameFromArray(kArray, kNumParts), FullQName());
        test.TestAllRecordRespondersAreNull();
    }

#if CHIP_CONFIG_MEMORY_DEBUG_DMALLOC
    // Count the memory that has not been freed at this point (since mark)
    unsigned long nAllocated = dmalloc_count_changed(mark, 1, 0);
    EXPECT_NE(nAllocated, 0);
#endif

    // Adding one more should fail.
    EXPECT_EQ(test.AllocateQNameFromArray(kArray, kNumParts), FullQName());
    test.TestAllRecordRespondersAreNull();

#if CHIP_CONFIG_MEMORY_DEBUG_DMALLOC
    // We should not have allocated any more memory
    EXPECT_EQ(nAllocated, dmalloc_count_changed(mark, 1, 0));
#endif

    // Clear should take us back to all empty.
    test.Clear();
    test.TestAllQNamesAreNull();
    test.TestAllRecordRespondersAreNull();

#if CHIP_CONFIG_MEMORY_DEBUG_DMALLOC
    // The amount of unfreed pointers should be 0.
    EXPECT_EQ(dmalloc_count_changed(mark, 1, 0), 0);
#endif
}

TEST_F(TestMinimalMdnsAllocator, TestQueryAllocatorRecordResponder)
{
    TestAllocator test;

#if CHIP_CONFIG_MEMORY_DEBUG_DMALLOC
    unsigned long mark = dmalloc_mark();
#endif
    // Start empty.
    test.TestAllRecordRespondersAreNull();
    test.TestAllQNamesAreNull();

    FullQName serviceName  = test.AllocateQName("test", "service");
    FullQName instanceName = test.AllocateQName("test", "instance");

    for (size_t i = 0; i < kMaxRecords; ++i)
    {
        EXPECT_TRUE(test.AddResponder<PtrResponder>(serviceName, instanceName).IsValid());
    }

#if CHIP_CONFIG_MEMORY_DEBUG_DMALLOC
    // Count the memory that has not been freed at this point (since mark)
    unsigned long nAllocated = dmalloc_count_changed(mark, 1, 0);
    EXPECT_NE(nAllocated, 0);
#endif

    // Adding one more should fail.
    EXPECT_FALSE(test.AddResponder<PtrResponder>(serviceName, instanceName).IsValid());
#if CHIP_CONFIG_MEMORY_DEBUG_DMALLOC
    // We should not have allocated any more memory
    EXPECT_EQ(nAllocated, dmalloc_count_changed(mark, 1, 0));
#endif

    // Clear should take us back to all empty.
    test.Clear();
    test.TestAllQNamesAreNull();
    test.TestAllRecordRespondersAreNull();

#if CHIP_CONFIG_MEMORY_DEBUG_DMALLOC
    // The amount of unfreed pointers should be 0.
    EXPECT_EQ(dmalloc_count_changed(mark, 1, 0), 0);
#endif
}

TEST_F(TestMinimalMdnsAllocator, TestQueryAllocatorRecordResponderTypes)
{
    TestAllocator test;

#if CHIP_CONFIG_MEMORY_DEBUG_DMALLOC
    unsigned long mark = dmalloc_mark();
#endif
    // Start empty.
    test.TestAllRecordRespondersAreNull();
    test.TestAllQNamesAreNull();

    FullQName serviceName  = test.AllocateQName("test", "service");
    FullQName instanceName = test.AllocateQName("test", "instance");
    FullQName hostName     = test.AllocateQName("test", "host");
    FullQName someTxt      = test.AllocateQName("L1=some text", "L2=some other text");

    EXPECT_NE(serviceName, FullQName());
    EXPECT_NE(instanceName, FullQName());
    EXPECT_NE(hostName, FullQName());
    EXPECT_NE(someTxt, FullQName());

    // Test that we can add all types
    EXPECT_TRUE(test.AddResponder<PtrResponder>(serviceName, instanceName).IsValid());
    EXPECT_TRUE(test.AddResponder<SrvResponder>(SrvResourceRecord(instanceName, hostName, 57)).IsValid());
    EXPECT_TRUE(test.AddResponder<TxtResponder>(TxtResourceRecord(instanceName, someTxt)).IsValid());
    EXPECT_TRUE(test.AddResponder<IPv6Responder>(hostName).IsValid());
    EXPECT_TRUE(test.AddResponder<IPv4Responder>(hostName).IsValid());

#if CHIP_CONFIG_MEMORY_DEBUG_DMALLOC
    // Count the memory that has not been freed at this point (since mark)
    unsigned long nAllocated = dmalloc_count_changed(mark, 1, 0);
    EXPECT_NE(nAllocated, 0);
#endif

    // Clear should take us back to all empty.
    test.Clear();
    test.TestAllQNamesAreNull();
    test.TestAllRecordRespondersAreNull();

#if CHIP_CONFIG_MEMORY_DEBUG_DMALLOC
    // The amount of unfreed pointers should be 0.
    EXPECT_EQ(dmalloc_count_changed(mark, 1, 0), 0);
#endif
}

TEST_F(TestMinimalMdnsAllocator, TestGetResponder)
{
    TestAllocator test;
    // Start empty.
    test.TestAllRecordRespondersAreNull();
    test.TestAllQNamesAreNull();

    FullQName serviceName  = test.AllocateQName("test", "service");
    FullQName instanceName = test.AllocateQName("test", "instance");
    FullQName hostName     = test.AllocateQName("test", "host");
    FullQName someTxt      = test.AllocateQName("L1=some text", "L2=some other text");
    FullQName notAdded     = test.AllocateQName("not", "added");

    EXPECT_NE(serviceName, FullQName());
    EXPECT_NE(instanceName, FullQName());
    EXPECT_NE(hostName, FullQName());
    EXPECT_NE(someTxt, FullQName());

    EXPECT_TRUE(test.AddResponder<PtrResponder>(serviceName, instanceName).IsValid());
    EXPECT_TRUE(test.AddResponder<SrvResponder>(SrvResourceRecord(instanceName, hostName, 57)).IsValid());
    EXPECT_TRUE(test.AddResponder<TxtResponder>(TxtResourceRecord(instanceName, someTxt)).IsValid());
    EXPECT_TRUE(test.AddResponder<IPv6Responder>(hostName).IsValid());
    EXPECT_TRUE(test.AddResponder<IPv4Responder>(hostName).IsValid());

    // These should all exist
    ASSERT_NE(test.GetResponder(QType::PTR, serviceName), nullptr);
    ASSERT_NE(test.GetResponder(QType::SRV, instanceName), nullptr);
    ASSERT_NE(test.GetResponder(QType::TXT, instanceName), nullptr);
    ASSERT_NE(test.GetResponder(QType::A, hostName), nullptr);
    ASSERT_NE(test.GetResponder(QType::AAAA, hostName), nullptr);

    // incorrect types
    EXPECT_EQ(test.GetResponder(QType::SRV, notAdded), nullptr);
    EXPECT_EQ(test.GetResponder(QType::AAAA, instanceName), nullptr);
    EXPECT_EQ(test.GetResponder(QType::A, instanceName), nullptr);
    EXPECT_EQ(test.GetResponder(QType::PTR, hostName), nullptr);
    EXPECT_EQ(test.GetResponder(QType::TXT, hostName), nullptr);

    // incorrect names
    EXPECT_EQ(test.GetResponder(QType::PTR, notAdded), nullptr);
    EXPECT_EQ(test.GetResponder(QType::SRV, notAdded), nullptr);
    EXPECT_EQ(test.GetResponder(QType::TXT, notAdded), nullptr);
    EXPECT_EQ(test.GetResponder(QType::A, notAdded), nullptr);
    EXPECT_EQ(test.GetResponder(QType::AAAA, notAdded), nullptr);
    test.Clear();
}

} // namespace

;
