/*
 * Copyright (C) 2011 Google Inc. All rights reserved.
 * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"

#include "Counters.h"
#include "MoveOnly.h"
#include "RefLogger.h"
#include <ranges>
#include <string>
#include <wtf/HashCountedSet.h>
#include <wtf/text/StringHash.h>

namespace TestWebKitAPI {

typedef WTF::HashCountedSet<int> IntHashCountedSet;

TEST(WTF_HashCountedSet, HashTableIteratorComparison)
{
    IntHashCountedSet hashCountedSet;
    hashCountedSet.add(1);
    ASSERT_TRUE(hashCountedSet.begin() != hashCountedSet.end());
    ASSERT_FALSE(hashCountedSet.begin() == hashCountedSet.end());

    IntHashCountedSet::const_iterator begin = hashCountedSet.begin();
    ASSERT_TRUE(begin == hashCountedSet.begin());
    ASSERT_TRUE(hashCountedSet.begin() == begin);
    ASSERT_TRUE(begin != hashCountedSet.end());
    ASSERT_TRUE(hashCountedSet.end() != begin);
    ASSERT_FALSE(begin != hashCountedSet.begin());
    ASSERT_FALSE(hashCountedSet.begin() != begin);
    ASSERT_FALSE(begin == hashCountedSet.end());
    ASSERT_FALSE(hashCountedSet.end() == begin);
}

struct TestDoubleHashTraits : HashTraits<double> {
    static const int minimumTableSize = 8;
};

typedef HashCountedSet<double, DefaultHash<double>, TestDoubleHashTraits> DoubleHashCountedSet;

static int bucketForKey(double key)
{
    return DefaultHash<double>::hash(key) & (TestDoubleHashTraits::minimumTableSize - 1);
}

TEST(WTF_HashCountedSet, DoubleHashCollisions)
{
    // The "clobber" key here is one that ends up stealing the bucket that the -0 key
    // originally wants to be in. This makes the 0 and -0 keys collide and the test then
    // fails unless the FloatHash::equals() implementation can distinguish them.
    const double clobberKey = 6;
    const double zeroKey = 0;
    const double negativeZeroKey = -zeroKey;

    DoubleHashCountedSet hashCountedSet;

    hashCountedSet.add(clobberKey);

    ASSERT_EQ(hashCountedSet.count(clobberKey), 1u);
    ASSERT_EQ(hashCountedSet.count(zeroKey), 0u);
    ASSERT_EQ(hashCountedSet.count(negativeZeroKey), 0u);

    hashCountedSet.add(zeroKey);
    hashCountedSet.add(negativeZeroKey);

    ASSERT_EQ(bucketForKey(clobberKey), bucketForKey(negativeZeroKey));
    ASSERT_EQ(hashCountedSet.count(clobberKey), 1u);
    ASSERT_EQ(hashCountedSet.count(zeroKey), 1u);
    ASSERT_EQ(hashCountedSet.count(negativeZeroKey), 1u);

    hashCountedSet.add(clobberKey);
    hashCountedSet.add(zeroKey);
    hashCountedSet.add(negativeZeroKey);

    ASSERT_EQ(hashCountedSet.count(clobberKey), 2u);
    ASSERT_EQ(hashCountedSet.count(zeroKey), 2u);
    ASSERT_EQ(hashCountedSet.count(negativeZeroKey), 2u);

    hashCountedSet.add(clobberKey, 12);
    hashCountedSet.add(zeroKey, 15);
    hashCountedSet.add(negativeZeroKey, 17);

    ASSERT_EQ(hashCountedSet.count(clobberKey), 14u);
    ASSERT_EQ(hashCountedSet.count(zeroKey), 17u);
    ASSERT_EQ(hashCountedSet.count(negativeZeroKey), 19u);
}

TEST(WTF_HashCountedSet, DoubleHashCollisionsInitialCount)
{
    // The "clobber" key here is one that ends up stealing the bucket that the -0 key
    // originally wants to be in. This makes the 0 and -0 keys collide and the test then
    // fails unless the FloatHash::equals() implementation can distinguish them.
    const double clobberKey = 6;
    const double zeroKey = 0;
    const double negativeZeroKey = -zeroKey;

    DoubleHashCountedSet hashCountedSet;

    hashCountedSet.add(clobberKey, 5);

    ASSERT_EQ(hashCountedSet.count(clobberKey), 5u);
    ASSERT_EQ(hashCountedSet.count(zeroKey), 0u);
    ASSERT_EQ(hashCountedSet.count(negativeZeroKey), 0u);

    hashCountedSet.add(zeroKey, 22);
    hashCountedSet.add(negativeZeroKey, 0);

    ASSERT_EQ(bucketForKey(clobberKey), bucketForKey(negativeZeroKey));
    ASSERT_EQ(hashCountedSet.count(clobberKey), 5u);
    ASSERT_EQ(hashCountedSet.count(zeroKey), 22u);
    ASSERT_EQ(hashCountedSet.count(negativeZeroKey), 0u);

    hashCountedSet.add(clobberKey);
    hashCountedSet.add(zeroKey);
    hashCountedSet.add(negativeZeroKey);

    ASSERT_EQ(hashCountedSet.count(clobberKey), 6u);
    ASSERT_EQ(hashCountedSet.count(zeroKey), 23u);
    ASSERT_EQ(hashCountedSet.count(negativeZeroKey), 1u);
}


TEST(WTF_HashCountedSet, MoveOnlyKeys)
{
    HashCountedSet<MoveOnly> moveOnlyKeys;

    for (size_t i = 0; i < 100; ++i) {
        MoveOnly moveOnly(i + 1);
        moveOnlyKeys.add(WTF::move(moveOnly));
    }

    for (size_t i = 0; i < 100; ++i) {
        auto it = moveOnlyKeys.find(MoveOnly(i + 1));
        ASSERT_FALSE(it == moveOnlyKeys.end());
        ASSERT_EQ(it->value, 1u);
    }

    for (size_t i = 0; i < 100; ++i)
        ASSERT_FALSE(moveOnlyKeys.add(MoveOnly(i + 1)).isNewEntry);

    for (size_t i = 0; i < 100; ++i)
        ASSERT_FALSE(moveOnlyKeys.remove(MoveOnly(i + 1)));

    for (size_t i = 0; i < 100; ++i)
        ASSERT_TRUE(moveOnlyKeys.remove(MoveOnly(i + 1)));

    ASSERT_TRUE(moveOnlyKeys.isEmpty());
}

TEST(WTF_HashCountedSet, MoveOnlyKeysInitialCount)
{
    HashCountedSet<MoveOnly> moveOnlyKeys;

    for (size_t i = 0; i < 100; ++i) {
        MoveOnly moveOnly(i + 1);
        moveOnlyKeys.add(WTF::move(moveOnly), i + 1);
    }

    for (size_t i = 0; i < 100; ++i) {
        auto it = moveOnlyKeys.find(MoveOnly(i + 1));
        ASSERT_FALSE(it == moveOnlyKeys.end());
        ASSERT_EQ(it->value, i + 1);
    }

    for (size_t i = 0; i < 100; ++i)
        ASSERT_FALSE(moveOnlyKeys.add(MoveOnly(i + 1)).isNewEntry);

    for (size_t i = 0; i < 100; ++i)
        ASSERT_EQ(moveOnlyKeys.count(MoveOnly(i + 1)), i + 2);

    for (size_t i = 0; i < 100; ++i)
        ASSERT_FALSE(moveOnlyKeys.remove(MoveOnly(i + 1)));

    for (size_t i = 0; i < 100; ++i)
        ASSERT_EQ(moveOnlyKeys.count(MoveOnly(i + 1)), i + 1);
}

TEST(WTF_HashCountedSet, InitializerList)
{
    HashCountedSet<String> hashCountedSet = {
        "one"_s,
        "two"_s,
        "three"_s,
        "four"_s,
        "four"_s,
        "four"_s,
        "four"_s,
    };

    EXPECT_EQ(4u, hashCountedSet.size());

    EXPECT_EQ(hashCountedSet.count("one"_s), 1u);
    EXPECT_EQ(hashCountedSet.count("two"_s), 1u);
    EXPECT_EQ(hashCountedSet.count("three"_s), 1u);
    EXPECT_EQ(hashCountedSet.count("four"_s), 4u);
}

TEST(WTF_HashCountedSet, InitializerListInitialCount)
{
    HashCountedSet<String> hashCountedSet = {
        { String("one"_s), 1u },
        { String("two"_s), 2u },
        { String("three"_s), 3u },
        { String("four"_s), 4u },
    };

    EXPECT_EQ(4u, hashCountedSet.size());

    EXPECT_EQ(hashCountedSet.count("one"_s), 1u);
    EXPECT_EQ(hashCountedSet.count("two"_s), 2u);
    EXPECT_EQ(hashCountedSet.count("three"_s), 3u);
    EXPECT_EQ(hashCountedSet.count("four"_s), 4u);
}

TEST(WTF_HashCountedSet, UniquePtrKey)
{
    ConstructorDestructorCounter::TestingScope scope;

    HashCountedSet<std::unique_ptr<ConstructorDestructorCounter>> hashCountedSet;

    auto uniquePtr = makeUnique<ConstructorDestructorCounter>();
    hashCountedSet.add(WTF::move(uniquePtr));

    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
    EXPECT_EQ(0u, ConstructorDestructorCounter::destructionCount);

    hashCountedSet.clear();

    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
    EXPECT_EQ(1u, ConstructorDestructorCounter::destructionCount);
}

TEST(WTF_HashCountedSet, UniquePtrKeyInitialCount)
{
    ConstructorDestructorCounter::TestingScope scope;

    HashCountedSet<std::unique_ptr<ConstructorDestructorCounter>> hashCountedSet;

    auto uniquePtr = makeUnique<ConstructorDestructorCounter>();
    hashCountedSet.add(WTF::move(uniquePtr), 12);

    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
    EXPECT_EQ(0u, ConstructorDestructorCounter::destructionCount);

    hashCountedSet.clear();

    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
    EXPECT_EQ(1u, ConstructorDestructorCounter::destructionCount);
}

TEST(WTF_HashCountedSet, UniquePtrKey_CustomDeleter)
{
    ConstructorDestructorCounter::TestingScope constructorDestructorCounterScope;
    DeleterCounter<ConstructorDestructorCounter>::TestingScope deleterCounterScope;

    HashCountedSet<std::unique_ptr<ConstructorDestructorCounter, DeleterCounter<ConstructorDestructorCounter>>> hashCountedSet;

    std::unique_ptr<ConstructorDestructorCounter, DeleterCounter<ConstructorDestructorCounter>> uniquePtr(new ConstructorDestructorCounter(), DeleterCounter<ConstructorDestructorCounter>());
    hashCountedSet.add(WTF::move(uniquePtr));

    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
    EXPECT_EQ(0u, ConstructorDestructorCounter::destructionCount);

    EXPECT_EQ(0u, DeleterCounter<ConstructorDestructorCounter>::deleterCount());

    hashCountedSet.clear();

    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
    EXPECT_EQ(1u, ConstructorDestructorCounter::destructionCount);

    EXPECT_EQ(1u, DeleterCounter<ConstructorDestructorCounter>::deleterCount());
}

TEST(WTF_HashCountedSet, UniquePtrKey_FindUsingRawPointer)
{
    HashCountedSet<std::unique_ptr<int>> hashCountedSet;

    auto uniquePtr = makeUniqueWithoutFastMallocCheck<int>(5);
    int* ptr = uniquePtr.get();
    hashCountedSet.add(WTF::move(uniquePtr));

    auto it = hashCountedSet.find(ptr);
    ASSERT_TRUE(it != hashCountedSet.end());
    EXPECT_EQ(ptr, it->key.get());
    EXPECT_EQ(1u, it->value);
}

TEST(WTF_HashCountedSet, UniquePtrKey_ContainsUsingRawPointer)
{
    HashCountedSet<std::unique_ptr<int>> hashCountedSet;

    auto uniquePtr = makeUniqueWithoutFastMallocCheck<int>(5);
    int* ptr = uniquePtr.get();
    hashCountedSet.add(WTF::move(uniquePtr));

    EXPECT_EQ(true, hashCountedSet.contains(ptr));
}

TEST(WTF_HashCountedSet, UniquePtrKey_GetUsingRawPointer)
{
    HashCountedSet<std::unique_ptr<int>> hashCountedSet;

    auto uniquePtr = makeUniqueWithoutFastMallocCheck<int>(5);
    int* ptr = uniquePtr.get();
    hashCountedSet.add(WTF::move(uniquePtr));

    int value = hashCountedSet.count(ptr);
    EXPECT_EQ(1, value);
}

TEST(WTF_HashCountedSet, UniquePtrKey_RemoveUsingRawPointer)
{
    ConstructorDestructorCounter::TestingScope scope;

    HashCountedSet<std::unique_ptr<ConstructorDestructorCounter>> hashCountedSet;

    auto uniquePtr = makeUnique<ConstructorDestructorCounter>();
    ConstructorDestructorCounter* ptr = uniquePtr.get();
    hashCountedSet.add(WTF::move(uniquePtr));

    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
    EXPECT_EQ(0u, ConstructorDestructorCounter::destructionCount);

    bool result = hashCountedSet.remove(ptr);
    EXPECT_EQ(true, result);

    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
    EXPECT_EQ(1u, ConstructorDestructorCounter::destructionCount);
}

TEST(WTF_HashCountedSet, RefPtrKey_Add)
{
    {
        DerivedRefLogger a("a");

        HashCountedSet<RefPtr<RefLogger>> hashCountedSet;

        RefPtr<RefLogger> ptr(&a);
        hashCountedSet.add(ptr);

        ASSERT_STREQ("ref(a) ref(a) ", takeLogStr().c_str());
        EXPECT_EQ(1U, hashCountedSet.count(ptr));
        EXPECT_EQ(1U, hashCountedSet.count(ptr.get()));
    }

    EXPECT_STREQ("deref(a) deref(a) ", takeLogStr().c_str());
}

TEST(WTF_HashCountedSet, RefPtrKey_AddUsingRelease)
{
    {
        DerivedRefLogger a("a");

        HashCountedSet<RefPtr<RefLogger>> hashCountedSet;

        RefPtr<RefLogger> ptr(&a);
        hashCountedSet.add(WTF::move(ptr));
    }

    EXPECT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());
}

TEST(WTF_HashCountedSet, RefPtrKey_AddUsingMove)
{
    {
        DerivedRefLogger a("a");

        HashCountedSet<RefPtr<RefLogger>> hashCountedSet;

        RefPtr<RefLogger> ptr(&a);
        hashCountedSet.add(WTF::move(ptr));
    }

    EXPECT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());
}

TEST(WTF_HashCountedSet, RefPtrKey_AddUsingRaw)
{
    {
        DerivedRefLogger a("a");

        HashCountedSet<RefPtr<RefLogger>> hashCountedSet;

        RefPtr<RefLogger> ptr(&a);
        hashCountedSet.add(ptr.get());

        EXPECT_STREQ("ref(a) ref(a) ", takeLogStr().c_str());
        EXPECT_EQ(1U, hashCountedSet.count(ptr));
        EXPECT_EQ(1U, hashCountedSet.count(ptr.get()));
    }

    EXPECT_STREQ("deref(a) deref(a) ", takeLogStr().c_str());
}

TEST(WTF_HashCountedSet, RefPtrKey_AddKeyAlreadyPresent)
{
    {
        DerivedRefLogger a("a");

        HashCountedSet<RefPtr<RefLogger>> hashCountedSet;

        {
            RefPtr<RefLogger> ptr(&a);
            hashCountedSet.add(ptr);
        }

        EXPECT_STREQ("ref(a) ref(a) deref(a) ", takeLogStr().c_str());

        {
            RefPtr<RefLogger> ptr2(&a);
            auto addResult = hashCountedSet.add(ptr2);
            EXPECT_FALSE(addResult.isNewEntry);
        }

        EXPECT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());
    }

    EXPECT_STREQ("deref(a) ", takeLogStr().c_str());
}

TEST(WTF_HashCountedSet, RefPtrKey_AddUsingReleaseKeyAlreadyPresent)
{
    {
        DerivedRefLogger a("a");

        HashCountedSet<RefPtr<RefLogger>> hashCountedSet;

        {
            RefPtr<RefLogger> ptr(&a);
            hashCountedSet.add(ptr);
        }

        EXPECT_STREQ("ref(a) ref(a) deref(a) ", takeLogStr().c_str());

        {
            RefPtr<RefLogger> ptr2(&a);
            auto addResult = hashCountedSet.add(WTF::move(ptr2));
            EXPECT_FALSE(addResult.isNewEntry);
        }

        EXPECT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());
    }

    EXPECT_STREQ("deref(a) ", takeLogStr().c_str());
}

TEST(WTF_HashCountedSet, RefPtrKey_AddUsingMoveKeyAlreadyPresent)
{
    {
        DerivedRefLogger a("a");

        HashCountedSet<RefPtr<RefLogger>> hashCountedSet;

        {
            RefPtr<RefLogger> ptr(&a);
            hashCountedSet.add(ptr);
        }

        EXPECT_STREQ("ref(a) ref(a) deref(a) ", takeLogStr().c_str());

        {
            RefPtr<RefLogger> ptr2(&a);
            auto addResult = hashCountedSet.add(WTF::move(ptr2));
            EXPECT_FALSE(addResult.isNewEntry);
        }

        EXPECT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());
    }

    EXPECT_STREQ("deref(a) ", takeLogStr().c_str());
}

TEST(WTF_HashCountedSet, Values)
{
    HashCountedSet<int> set { 1, 1, 2, 3, 3 };
    
    auto vector = copyToVector(set.values());
    EXPECT_EQ(3U, vector.size());

    std::ranges::sort(vector);
    EXPECT_EQ(1, vector[0]);
    EXPECT_EQ(2, vector[1]);
    EXPECT_EQ(3, vector[2]);
}

} // namespace TestWebKitAPI
