/*
 * 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/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

