// Copyright 2021 The Tint Authors.
//
// 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 "src/tint/fuzzers/random_generator.h"

#include <memory>

#include "gtest/gtest.h"

#include "src/tint/fuzzers/mersenne_twister_engine.h"

namespace tint::fuzzers {
namespace {

/// Implementation of RandomGeneratorEngine that just returns a stream of
/// monotonically increasing numbers.
class MonotonicEngine : public RandomGeneratorEngine {
  public:
    uint32_t RandomUInt32(uint32_t, uint32_t) override { return next_++; }

    uint64_t RandomUInt64(uint64_t, uint64_t) override { return next_++; }

    void RandomNBytes(uint8_t*, size_t) override {
        assert(false && "MonotonicDelegate does not implement RandomNBytes");
    }

  private:
    uint32_t next_ = 0;
};

class RandomGeneratorTest : public testing::Test {
  public:
    void SetUp() override { rng_ = std::make_unique<RandomGenerator>(0); }

    void TearDown() override {}

  protected:
    std::unique_ptr<RandomGenerator> rng_;
};

#ifndef NDEBUG
TEST_F(RandomGeneratorTest, GetUInt32ReversedBoundsCrashes) {
    EXPECT_DEATH_IF_SUPPORTED(rng_->GetUInt32(10, 5), ".*");
}

TEST_F(RandomGeneratorTest, GetUInt32EmptyBoundsCrashes) {
    EXPECT_DEATH_IF_SUPPORTED(rng_->GetUInt32(5, 5), ".*");
}

TEST_F(RandomGeneratorTest, GetUInt32ZeroBoundCrashes) {
    EXPECT_DEATH_IF_SUPPORTED(rng_->GetUInt32(0u), ".*");
}
#endif  // NDEBUG

TEST_F(RandomGeneratorTest, GetUInt32SingularReturnsOneValue) {
    {
        uint32_t result = rng_->GetUInt32(5u, 6u);
        ASSERT_EQ(5u, result);
    }
    {
        uint32_t result = rng_->GetUInt32(1u);
        ASSERT_EQ(0u, result);
    }
}

TEST_F(RandomGeneratorTest, GetUInt32StaysInBounds) {
    {
        uint32_t result = rng_->GetUInt32(5u, 10u);
        ASSERT_LE(5u, result);
        ASSERT_GT(10u, result);
    }
    {
        uint32_t result = rng_->GetUInt32(10u);
        ASSERT_LE(0u, result);
        ASSERT_GT(10u, result);
    }
}

#ifndef NDEBUG
TEST_F(RandomGeneratorTest, GetUInt64ReversedBoundsCrashes) {
    EXPECT_DEATH_IF_SUPPORTED(rng_->GetUInt64(10, 5), ".*");
}

TEST_F(RandomGeneratorTest, GetUInt64EmptyBoundsCrashes) {
    EXPECT_DEATH_IF_SUPPORTED(rng_->GetUInt64(5, 5), ".*");
}

TEST_F(RandomGeneratorTest, GetUInt64ZeroBoundCrashes) {
    EXPECT_DEATH_IF_SUPPORTED(rng_->GetUInt64(0u), ".*");
}
#endif  // NDEBUG

TEST_F(RandomGeneratorTest, GetUInt64SingularReturnsOneValue) {
    {
        uint64_t result = rng_->GetUInt64(5u, 6u);
        ASSERT_EQ(5u, result);
    }
    {
        uint64_t result = rng_->GetUInt64(1u);
        ASSERT_EQ(0u, result);
    }
}

TEST_F(RandomGeneratorTest, GetUInt64StaysInBounds) {
    {
        uint64_t result = rng_->GetUInt64(5u, 10u);
        ASSERT_LE(5u, result);
        ASSERT_GT(10u, result);
    }
    {
        uint64_t result = rng_->GetUInt64(10u);
        ASSERT_LE(0u, result);
        ASSERT_GT(10u, result);
    }
}

TEST_F(RandomGeneratorTest, GetByte) {
    rng_->GetByte();
}

#ifndef NDEBUG
TEST_F(RandomGeneratorTest, GetNBytesNullDataBufferCrashes) {
    EXPECT_DEATH_IF_SUPPORTED(rng_->GetNBytes(nullptr, 5), ".*");
}
#endif  // NDEBUG

TEST_F(RandomGeneratorTest, GetNBytes) {
    std::vector<uint8_t> data;
    for (uint32_t i = 25; i < 1000u; i = i + 25) {
        data.resize(i);
        rng_->GetNBytes(data.data(), data.size());
    }
}

TEST_F(RandomGeneratorTest, GetBool) {
    rng_->GetBool();
}

TEST_F(RandomGeneratorTest, GetWeightedBoolZeroAlwaysFalse) {
    ASSERT_FALSE(rng_->GetWeightedBool(0));
}

TEST_F(RandomGeneratorTest, GetWeightedBoolHundredAlwaysTrue) {
    ASSERT_TRUE(rng_->GetWeightedBool(100));
}

#ifndef NDEBUG
TEST_F(RandomGeneratorTest, GetWeightedBoolAboveHundredCrashes) {
    EXPECT_DEATH_IF_SUPPORTED(rng_->GetWeightedBool(101), ".*");
    EXPECT_DEATH_IF_SUPPORTED(rng_->GetWeightedBool(500), ".*");
}
#endif  // NDEBUG

TEST_F(RandomGeneratorTest, GetWeightedBool) {
    for (uint32_t i = 0; i <= 100; i++) {
        rng_ = std::make_unique<RandomGenerator>(std::make_unique<MonotonicEngine>());
        for (uint32_t j = 0; j <= 100; j++) {
            if (j < i) {
                ASSERT_TRUE(rng_->GetWeightedBool(i));
            } else {
                ASSERT_FALSE(rng_->GetWeightedBool(i));
            }
        }
    }
}

#ifndef NDEBUG
TEST_F(RandomGeneratorTest, GetRandomElementEmptyVectorCrashes) {
    std::vector<uint8_t> v;
    EXPECT_DEATH_IF_SUPPORTED(rng_->GetRandomElement(v), ".*");
}
#endif  // NDEBUG

TEST_F(RandomGeneratorTest, GetRandomElement) {
    std::vector<uint32_t> v;
    for (uint32_t i = 25; i < 100u; i = i + 25) {
        rng_ = std::make_unique<RandomGenerator>(std::make_unique<MonotonicEngine>());
        v.resize(i);
        std::iota(v.begin(), v.end(), 0);
        for (uint32_t j = 0; j < i; j++) {
            EXPECT_EQ(j, rng_->GetRandomElement(v));
        }
    }
}

}  // namespace
}  // namespace tint::fuzzers
