/*
 * 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/Varint.h>

#include <array>
#include <initializer_list>
#include <random>
#include <vector>

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

#include <folly/Benchmark.h>
#include <folly/Random.h>

DEFINE_int32(random_seed, folly::randomNumberSeed(), "random seed");

namespace folly { namespace test {

void testVarint(uint64_t val, std::initializer_list<uint8_t> bytes) {
  size_t n = bytes.size();
  ByteRange expected(&*bytes.begin(), n);

  {
    uint8_t buf[kMaxVarintLength64];
    EXPECT_EQ(expected.size(), encodeVarint(val, buf));
    EXPECT_TRUE(ByteRange(buf, expected.size()) == expected);
  }

  {
    ByteRange r = expected;
    uint64_t decoded = decodeVarint(r);
    EXPECT_TRUE(r.empty());
    EXPECT_EQ(val, decoded);
  }

  if (n < kMaxVarintLength64) {
    // Try from a full buffer too, different code path
    uint8_t buf[kMaxVarintLength64];
    memcpy(buf, &*bytes.begin(), n);

    uint8_t fills[] = {0, 0x7f, 0x80, 0xff};

    for (uint8_t fill : fills) {
      memset(buf + n, fill, kMaxVarintLength64 - n);
      ByteRange r(buf, kMaxVarintLength64);
      uint64_t decoded = decodeVarint(r);
      EXPECT_EQ(val, decoded);
      EXPECT_EQ(kMaxVarintLength64 - n, r.size());
    }
  }
}

TEST(Varint, Interface) {
  // Make sure decodeVarint() accepts all of StringPiece, MutableStringPiece,
  // ByteRange, and MutableByteRange.
  char c = 0;

  StringPiece sp(&c, 1);
  EXPECT_EQ(decodeVarint(sp), 0);

  MutableStringPiece msp(&c, 1);
  EXPECT_EQ(decodeVarint(msp), 0);

  ByteRange br(reinterpret_cast<unsigned char*>(&c), 1);
  EXPECT_EQ(decodeVarint(br), 0);

  MutableByteRange mbr(reinterpret_cast<unsigned char*>(&c), 1);
  EXPECT_EQ(decodeVarint(mbr), 0);
}

TEST(Varint, Simple) {
  testVarint(0, {0});
  testVarint(1, {1});
  testVarint(127, {127});
  testVarint(128, {0x80, 0x01});
  testVarint(300, {0xac, 0x02});
  testVarint(16383, {0xff, 0x7f});
  testVarint(16384, {0x80, 0x80, 0x01});

  testVarint(static_cast<uint32_t>(-1),
             {0xff, 0xff, 0xff, 0xff, 0x0f});
  testVarint(static_cast<uint64_t>(-1),
             {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01});
}

TEST(ZigZag, Simple) {
  EXPECT_EQ(0, encodeZigZag(0));
  EXPECT_EQ(1, encodeZigZag(-1));
  EXPECT_EQ(2, encodeZigZag(1));
  EXPECT_EQ(3, encodeZigZag(-2));
  EXPECT_EQ(4, encodeZigZag(2));

  EXPECT_EQ(0,  decodeZigZag(0));
  EXPECT_EQ(-1, decodeZigZag(1));
  EXPECT_EQ(1,  decodeZigZag(2));
  EXPECT_EQ(-2, decodeZigZag(3));
  EXPECT_EQ(2,  decodeZigZag(4));
}

namespace {

constexpr size_t kNumValues = 1000;
std::vector<uint64_t> gValues;
std::vector<uint64_t> gDecodedValues;
std::vector<uint8_t> gEncoded;

void generateRandomValues() {
  LOG(INFO) << "Random seed is " << FLAGS_random_seed;
  std::mt19937 rng(FLAGS_random_seed);

  // Approximation of power law
  std::uniform_int_distribution<int> numBytes(1, 8);
  std::uniform_int_distribution<int> byte(0, 255);

  gValues.resize(kNumValues);
  gDecodedValues.resize(kNumValues);
  gEncoded.resize(kNumValues * kMaxVarintLength64);
  for (size_t i = 0; i < kNumValues; ++i) {
    int n = numBytes(rng);
    uint64_t val = 0;
    for (int j = 0; j < n; ++j) {
      val = (val << 8) + byte(rng);
    }
    gValues[i] = val;
  }
}

// Benchmark results (Intel(R) Xeon(R) CPU E5-2660 0 @ 2.20GHz, Linux x86_64)
//
// I0814 19:13:14.466256  7504 VarintTest.cpp:146] Random seed is -1216518886
// ============================================================================
// folly/test/VarintTest.cpp                       relative  time/iter  iters/s
// ============================================================================
// VarintEncoding                                               6.69us  149.37K
// VarintDecoding                                               6.85us  145.90K
// ============================================================================
//
// Disabling the "fast path" code in decodeVarint hurts performance:
//
// I0814 19:15:13.871467  9550 VarintTest.cpp:156] Random seed is -1216518886
// ============================================================================
// folly/test/VarintTest.cpp                       relative  time/iter  iters/s
// ============================================================================
// VarintEncoding                                               6.75us  148.26K
// VarintDecoding                                              12.60us   79.37K
// ============================================================================

BENCHMARK(VarintEncoding, iters) {
  uint8_t* start = &(*gEncoded.begin());
  uint8_t* p = start;
  bool empty = (iters == 0);
  while (iters--) {
    p = start;
    for (auto& v : gValues) {
      p += encodeVarint(v, p);
    }
  }

  gEncoded.erase(gEncoded.begin() + (p - start), gEncoded.end());
}

BENCHMARK(VarintDecoding, iters) {
  while (iters--) {
    size_t i = 0;
    ByteRange range(&(*gEncoded.begin()), &(*gEncoded.end()));
    while (!range.empty()) {
      gDecodedValues[i++] = decodeVarint(range);
    }
  }
}

}  // namespace

}}  // namespaces

int main(int argc, char *argv[]) {
  testing::InitGoogleTest(&argc, argv);
  gflags::ParseCommandLineFlags(&argc, &argv, true);
  google::InitGoogleLogging(argv[0]);
  int ret = RUN_ALL_TESTS();
  if (ret == 0) {
    folly::test::generateRandomValues();
    folly::runBenchmarksOnFlag();
  }
  return ret;
}
