/*
 * Copyright (C) 2014 Google 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:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * 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.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
 * OWNER OR 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 "sky/engine/config.h"
#include "sky/engine/platform/PurgeableVector.h"

#include "sky/engine/platform/TestingPlatformSupport.h"
#include "sky/engine/public/platform/WebDiscardableMemory.h"
#include "sky/engine/wtf/Vector.h"

#include <algorithm>
#include <cstdlib>

#include <gtest/gtest.h>

using namespace blink;

namespace {

const size_t kTestSize = 32 * 1024;

enum DiscardableMemorySupport {
    DontSupportDiscardableMemory,
    SupportDiscardableMemory,
};

class PurgeableVectorTestWithPlatformSupport : public testing::TestWithParam<DiscardableMemorySupport> {
public:
    PurgeableVectorTestWithPlatformSupport() : m_testingPlatformSupport(makeTestingPlatformSupportConfig()) { }

protected:
    bool isDiscardableMemorySupported() const { return GetParam() == SupportDiscardableMemory; }

    TestingPlatformSupport::Config makeTestingPlatformSupportConfig() const
    {
        TestingPlatformSupport::Config config;
        config.hasDiscardableMemorySupport = isDiscardableMemorySupported();
        return config;
    }

    PurgeableVector::PurgeableOption makePurgeableOption() const
    {
        return isDiscardableMemorySupported() ? PurgeableVector::Purgeable : PurgeableVector::NotPurgeable;
    }

private:
    TestingPlatformSupport m_testingPlatformSupport;
};

TEST_P(PurgeableVectorTestWithPlatformSupport, grow)
{
    PurgeableVector purgeableVector(makePurgeableOption());
    purgeableVector.grow(kTestSize);
    ASSERT_EQ(kTestSize, purgeableVector.size());
    // Make sure the underlying buffer was actually (re)allocated.
    memset(purgeableVector.data(), 0, purgeableVector.size());
}

TEST_P(PurgeableVectorTestWithPlatformSupport, clear)
{
    Vector<char> testData(kTestSize);
    std::generate(testData.begin(), testData.end(), &std::rand);

    PurgeableVector purgeableVector(makePurgeableOption());
    purgeableVector.append(testData.data(), testData.size());
    EXPECT_EQ(testData.size(), purgeableVector.size());

    purgeableVector.clear();
    EXPECT_EQ(0U, purgeableVector.size());
    EXPECT_EQ(0, purgeableVector.data());
}

TEST_P(PurgeableVectorTestWithPlatformSupport, clearDoesNotResetLockCounter)
{
    PurgeableVector purgeableVector(makePurgeableOption());
    purgeableVector.clear();
    EXPECT_TRUE(purgeableVector.isLocked());
    purgeableVector.unlock();
    EXPECT_FALSE(purgeableVector.isLocked());
}

TEST_P(PurgeableVectorTestWithPlatformSupport, reserveCapacityDoesNotChangeSize)
{
    PurgeableVector purgeableVector(makePurgeableOption());
    EXPECT_EQ(0U, purgeableVector.size());
    purgeableVector.reserveCapacity(kTestSize);
    EXPECT_EQ(0U, purgeableVector.size());
}

TEST_P(PurgeableVectorTestWithPlatformSupport, multipleAppends)
{
    Vector<char> testData(kTestSize);
    std::generate(testData.begin(), testData.end(), &std::rand);

    PurgeableVector purgeableVector(makePurgeableOption());
    // Force an allocation.
    const char kSmallString[] = "hello";
    purgeableVector.append(kSmallString, sizeof(kSmallString));
    const char* const data = purgeableVector.data();

    // Append all the testing data in 4 iterations. The |data| pointer should
    // have been changed at the end of the unit test due to reallocations.
    const size_t kIterationCount = 4;
    ASSERT_EQ(0U, testData.size() % kIterationCount);
    for (size_t i = 0; i < kIterationCount; ++i) {
        const char* const testDataStart = testData.data() + i * (testData.size() / kIterationCount);
        purgeableVector.append(testDataStart, testData.size() / kIterationCount);
        ASSERT_EQ((i + 1) * testData.size() / kIterationCount, purgeableVector.size() - sizeof(kSmallString));
    }

    ASSERT_EQ(sizeof(kSmallString) + testData.size(), purgeableVector.size());
    EXPECT_NE(data, purgeableVector.data());
    EXPECT_EQ(0, memcmp(purgeableVector.data() + sizeof(kSmallString), testData.data(), testData.size()));
}

TEST_P(PurgeableVectorTestWithPlatformSupport, multipleAppendsAfterReserveCapacity)
{
    Vector<char> testData(kTestSize);
    std::generate(testData.begin(), testData.end(), &std::rand);

    PurgeableVector purgeableVector(makePurgeableOption());
    purgeableVector.reserveCapacity(testData.size());
    const char* const data = purgeableVector.data();

    // The |data| pointer should be unchanged at the end of the unit test
    // meaning that there should not have been any reallocation.
    const size_t kIterationCount = 4;
    ASSERT_EQ(0U, testData.size() % kIterationCount);
    for (size_t i = 0; i < kIterationCount; ++i) {
        const char* const testDataStart = testData.data() + i * (testData.size() / kIterationCount);
        purgeableVector.append(testDataStart, testData.size() / kIterationCount);
        ASSERT_EQ((i + 1) * testData.size() / kIterationCount, purgeableVector.size());
    }

    ASSERT_EQ(testData.size(), purgeableVector.size());
    EXPECT_EQ(data, purgeableVector.data());
    EXPECT_EQ(0, memcmp(purgeableVector.data(), testData.data(), testData.size()));
}

TEST_P(PurgeableVectorTestWithPlatformSupport, reserveCapacityUsesExactCapacityWhenVectorIsEmpty)
{
    Vector<char> testData(kTestSize);
    std::generate(testData.begin(), testData.end(), &std::rand);

    PurgeableVector purgeableVector(makePurgeableOption());
    purgeableVector.reserveCapacity(kTestSize);
    const char* const data = purgeableVector.data();

    purgeableVector.append(testData.data(), testData.size());
    EXPECT_EQ(data, purgeableVector.data());
    EXPECT_EQ(0, memcmp(purgeableVector.data(), testData.data(), testData.size()));

    // This test is not reliable if the PurgeableVector uses a plain WTF::Vector
    // for storage, as it does if discardable memory is not supported; the vectors
    // capacity will always be expanded to fill the PartitionAlloc bucket.
    if (isDiscardableMemorySupported()) {
        // Appending one extra byte should cause a reallocation since the first
        // allocation happened while the purgeable vector was empty. This behavior
        // helps us guarantee that there is no memory waste on very small vectors
        // (which SharedBuffer requires).
        purgeableVector.append(testData.data(), 1);
        EXPECT_NE(data, purgeableVector.data());
    }
}

TEST_P(PurgeableVectorTestWithPlatformSupport, appendReservesCapacityIfNeeded)
{
    Vector<char> testData(kTestSize);
    std::generate(testData.begin(), testData.end(), &std::rand);

    PurgeableVector purgeableVector(makePurgeableOption());
    // No reserveCapacity().
    ASSERT_FALSE(purgeableVector.data());

    purgeableVector.append(testData.data(), testData.size());
    ASSERT_EQ(testData.size(), purgeableVector.size());
    ASSERT_EQ(0, memcmp(purgeableVector.data(), testData.data(), testData.size()));
}

TEST_P(PurgeableVectorTestWithPlatformSupport, adopt)
{
    Vector<char> testData(kTestSize);
    std::generate(testData.begin(), testData.end(), &std::rand);
    const Vector<char> testDataCopy(testData);
    const char* const testDataPtr = testData.data();

    PurgeableVector purgeableVector(makePurgeableOption());
    purgeableVector.adopt(testData);
    EXPECT_TRUE(testData.isEmpty());
    EXPECT_EQ(kTestSize, purgeableVector.size());
    ASSERT_EQ(0, memcmp(purgeableVector.data(), testDataCopy.data(), testDataCopy.size()));

    if (isDiscardableMemorySupported()) {
        // An extra discardable memory allocation + memcpy() should have happened.
        EXPECT_NE(testDataPtr, purgeableVector.data());
    } else {
        // Vector::swap() should have been used.
        EXPECT_EQ(testDataPtr, purgeableVector.data());
    }
}

TEST_P(PurgeableVectorTestWithPlatformSupport, adoptEmptyVector)
{
    Vector<char> testData;
    PurgeableVector purgeableVector(makePurgeableOption());
    purgeableVector.adopt(testData);
}

TEST(PurgeableVectorTestWithPlatformSupport, adoptDiscardsPreviousData)
{
    Vector<char> testData;
    std::generate(testData.begin(), testData.end(), &std::rand);

    PurgeableVector purgeableVector(PurgeableVector::NotPurgeable);
    static const char smallString[] = "hello";
    purgeableVector.append(smallString, sizeof(smallString));
    ASSERT_EQ(0, memcmp(purgeableVector.data(), smallString, sizeof(smallString)));

    purgeableVector.adopt(testData);
    EXPECT_EQ(testData.size(), purgeableVector.size());
    ASSERT_EQ(0, memcmp(purgeableVector.data(), testData.data(), testData.size()));
}

TEST_P(PurgeableVectorTestWithPlatformSupport, unlockWithoutHintAtConstruction)
{
    Vector<char> testData(30000);
    std::generate(testData.begin(), testData.end(), &std::rand);

    unsigned length = testData.size();
    PurgeableVector purgeableVector(PurgeableVector::NotPurgeable);
    purgeableVector.append(testData.data(), length);
    ASSERT_EQ(length, purgeableVector.size());
    const char* data = purgeableVector.data();

    purgeableVector.unlock();

    // Note that the purgeable vector must be locked before calling data().
    const bool wasPurged = !purgeableVector.lock();
    if (isDiscardableMemorySupported()) {
        // The implementation of purgeable memory used for testing always purges data upon unlock().
        EXPECT_TRUE(wasPurged);
    }

    if (isDiscardableMemorySupported()) {
        // The data should have been moved from the heap-allocated vector to a purgeable buffer.
        ASSERT_NE(data, purgeableVector.data());
    } else {
        ASSERT_EQ(data, purgeableVector.data());
    }

    if (!wasPurged)
        ASSERT_EQ(0, memcmp(purgeableVector.data(), testData.data(), length));
}

TEST(PurgeableVectorTest, unlockOnEmptyPurgeableVector)
{
    PurgeableVector purgeableVector;
    ASSERT_EQ(0U, purgeableVector.size());
    purgeableVector.unlock();
    ASSERT_FALSE(purgeableVector.isLocked());
}

TEST_P(PurgeableVectorTestWithPlatformSupport, unlockOnPurgeableVectorWithPurgeableHint)
{
    Vector<char> testData(kTestSize);
    std::generate(testData.begin(), testData.end(), &std::rand);

    PurgeableVector purgeableVector;
    purgeableVector.append(testData.data(), kTestSize);
    const char* const data = purgeableVector.data();

    // unlock() should happen in place, i.e. without causing any reallocation.
    // Note that the instance must be locked when data() is called.
    purgeableVector.unlock();
    EXPECT_FALSE(purgeableVector.isLocked());
    purgeableVector.lock();
    EXPECT_TRUE(purgeableVector.isLocked());
    EXPECT_EQ(data, purgeableVector.data());
}

TEST_P(PurgeableVectorTestWithPlatformSupport, lockingUsesACounter)
{
    Vector<char> testData(kTestSize);
    std::generate(testData.begin(), testData.end(), &std::rand);

    PurgeableVector purgeableVector(PurgeableVector::NotPurgeable);
    purgeableVector.append(testData.data(), testData.size());
    ASSERT_EQ(testData.size(), purgeableVector.size());

    ASSERT_TRUE(purgeableVector.isLocked()); // SharedBuffer is locked at creation.
    ASSERT_TRUE(purgeableVector.lock()); // Add an extra lock.
    ASSERT_TRUE(purgeableVector.isLocked());

    purgeableVector.unlock();
    ASSERT_TRUE(purgeableVector.isLocked());

    purgeableVector.unlock();
    ASSERT_FALSE(purgeableVector.isLocked());

    if (purgeableVector.lock())
        ASSERT_EQ(0, memcmp(purgeableVector.data(), testData.data(), testData.size()));
}

// Instantiates all the unit tests using the SharedBufferTestWithPlatformSupport fixture both with
// and without discardable memory support.
INSTANTIATE_TEST_CASE_P(testsWithPlatformSetUp, PurgeableVectorTestWithPlatformSupport,
    ::testing::Values(DontSupportDiscardableMemory, SupportDiscardableMemory));

} // namespace

