/*
 * Copyright 2015 Facebook, Inc.
 *
 * 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 <folly/Random.h>
#include <folly/Range.h>
#include <folly/Benchmark.h>
#include <folly/Foreach.h>

#include <glog/logging.h>
#include <gtest/gtest.h>

#include <algorithm>
#include <thread>
#include <vector>
#include <random>

using namespace folly;

TEST(Random, StateSize) {
  using namespace folly::detail;

  // uint_fast32_t is uint64_t on x86_64, w00t
  EXPECT_EQ(sizeof(uint_fast32_t) / 4 + 3,
            StateSize<std::minstd_rand0>::value);
  EXPECT_EQ(624, StateSize<std::mt19937>::value);
#if FOLLY_USE_SIMD_PRNG
  EXPECT_EQ(624, StateSize<__gnu_cxx::sfmt19937>::value);
#endif
  EXPECT_EQ(24, StateSize<std::ranlux24_base>::value);
}

TEST(Random, Simple) {
  uint32_t prev = 0, seed = 0;
  for (int i = 0; i < 1024; ++i) {
    EXPECT_NE(seed = randomNumberSeed(), prev);
    prev = seed;
  }
}

TEST(Random, MultiThreaded) {
  const int n = 100;
  std::vector<uint32_t> seeds(n);
  std::vector<std::thread> threads;
  for (int i = 0; i < n; ++i) {
    threads.push_back(std::thread([i, &seeds] {
      seeds[i] = randomNumberSeed();
    }));
  }
  for (auto& t : threads) {
    t.join();
  }
  std::sort(seeds.begin(), seeds.end());
  for (int i = 0; i < n-1; ++i) {
    EXPECT_LT(seeds[i], seeds[i+1]);
  }
}

BENCHMARK(minstdrand, n) {
  BenchmarkSuspender braces;
  std::random_device rd;
  std::minstd_rand rng(rd());

  braces.dismiss();

  FOR_EACH_RANGE (i, 0, n) {
    doNotOptimizeAway(rng());
  }
}

BENCHMARK(mt19937, n) {
  BenchmarkSuspender braces;
  std::random_device rd;
  std::mt19937 rng(rd());

  braces.dismiss();

  FOR_EACH_RANGE (i, 0, n) {
    doNotOptimizeAway(rng());
  }
}

BENCHMARK(threadprng, n) {
  BenchmarkSuspender braces;
  ThreadLocalPRNG tprng;
  tprng();

  braces.dismiss();

  FOR_EACH_RANGE (i, 0, n) {
    doNotOptimizeAway(tprng());
  }
}

BENCHMARK(RandomDouble) { doNotOptimizeAway(Random::randDouble01()); }
BENCHMARK(Random32) { doNotOptimizeAway(Random::rand32()); }
BENCHMARK(Random32Num) { doNotOptimizeAway(Random::rand32(100)); }
BENCHMARK(Random64) { doNotOptimizeAway(Random::rand64()); }
BENCHMARK(Random64Num) { doNotOptimizeAway(Random::rand64(100ul << 32)); }
BENCHMARK(Random64OneIn) { doNotOptimizeAway(Random::oneIn(100)); }

int main(int argc, char** argv) {
  testing::InitGoogleTest(&argc, argv);
  gflags::ParseCommandLineFlags(&argc, &argv, true);

  if (FLAGS_benchmark) {
    folly::runBenchmarks();
  }
  return RUN_ALL_TESTS();
}
