/*
 * 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/Bits.h>
#include <folly/Benchmark.h>

#include <algorithm>
#include <type_traits>
#include <limits>
#include <vector>
#include <gtest/gtest.h>

#include <gflags/gflags.h>

using namespace folly;
using namespace folly::bititerator_detail;

namespace {

template <class INT, class IT>
void checkIt(INT exp, IT& it) {
  typedef typename std::make_unsigned<INT>::type utype;
  size_t bits = std::numeric_limits<utype>::digits;
  utype uexp = exp;
  for (size_t i = 0; i < bits; ++i) {
    bool e = uexp & 1;
    EXPECT_EQ(e, *it++);
    uexp >>= 1;
  }
}

template <class INT, class IT>
void checkRange(INT exp, IT begin, IT end) {
  typedef typename std::make_unsigned<INT>::type utype;
  utype uexp = exp;
  size_t i = 0;
  auto bitEnd = makeBitIterator(end);
  for (BitIterator<IT> it = makeBitIterator(begin); it != bitEnd; ++it, ++i) {
    bool e = uexp & 1;
    EXPECT_EQ(e, *it);
    uexp >>= 1;
  }
}

}  // namespace

TEST(BitIterator, Simple) {
  std::vector<int> v;
  v.push_back(0x10);
  v.push_back(0x42);
  auto bi(makeBitIterator(v.begin()));
  checkIt(0x10, bi);
  checkIt(0x42, bi);
  checkRange(0x0000004200000010ULL, v.begin(), v.end());

  v[0] = 0;
  bi = v.begin();
  *bi++ = true;     // 1
  *bi++ = false;
  *bi++ = true;     // 4
  *bi++ = false;
  *bi++ = false;
  *bi++ = true;     // 32
  *++bi = true;     // 128 (note pre-increment)

  EXPECT_EQ(165, v[0]);
}

TEST(BitIterator, Const) {
  std::vector<int> v;
  v.push_back(0x10);
  v.push_back(0x42);
  auto bi(makeBitIterator(v.cbegin()));
  checkIt(0x10, bi);
  checkIt(0x42, bi);
}

namespace {

template <class BaseIter>
BitIterator<BaseIter> simpleFFS(BitIterator<BaseIter> begin,
                                BitIterator<BaseIter> end) {
  return std::find(begin, end, true);
}

template <class FFS>
void runFFSTest(FFS fn) {
  static const size_t bpb = 8 * sizeof(uint64_t);
  std::vector<uint64_t> data;
  for (size_t nblocks = 1; nblocks <= 3; ++nblocks) {
    size_t nbits = nblocks * bpb;
    data.resize(nblocks);
    auto begin = makeBitIterator(data.cbegin());
    auto end = makeBitIterator(data.cend());
    EXPECT_EQ(nbits, end - begin);
    EXPECT_FALSE(begin == end);

    // Try every possible combination of first bit set (including none),
    // start bit, end bit
    for (size_t firstSet = 0; firstSet <= nbits; ++firstSet) {
      data.assign(nblocks, 0);
      if (firstSet) {
        size_t b = firstSet - 1;
        data[b / bpb] |= (1ULL << (b % bpb));
      }
      for (size_t startBit = 0; startBit <= nbits; ++startBit) {
        for (size_t endBit = startBit; endBit <= nbits; ++endBit) {
          auto p = begin + startBit;
          auto q = begin + endBit;
          p = fn(p, q);
          if (firstSet < startBit + 1 || firstSet >= endBit + 1) {
            EXPECT_EQ(endBit, p - begin)
              << "  firstSet=" << firstSet << " startBit=" << startBit
              << " endBit=" << endBit << " nblocks=" << nblocks;
          } else {
            EXPECT_EQ(firstSet - 1, p - begin)
              << "  firstSet=" << firstSet << " startBit=" << startBit
              << " endBit=" << endBit << " nblocks=" << nblocks;
          }
        }
      }
    }
  }
}

void runSimpleFFSTest(int iters) {
  auto fn = simpleFFS<std::vector<uint64_t>::const_iterator>;
  while (iters--) {
    runFFSTest(fn);
  }
}

void runRealFFSTest(int iters) {
  auto fn = findFirstSet<std::vector<uint64_t>::const_iterator>;
  while (iters--) {
    runFFSTest(fn);
  }
}

}

TEST(BitIterator, SimpleFindFirstSet) {
  runSimpleFFSTest(1);
}

TEST(BitIterator, FindFirstSet) {
  runRealFFSTest(1);
}

BENCHMARK(SimpleFFSTest, iters) {
  runSimpleFFSTest(iters);
}
BENCHMARK(RealFFSTest, iters) {
  runRealFFSTest(iters);
}

/* --bm_min_iters=10 --bm_max_iters=100

Benchmark                               Iters   Total t    t/iter iter/sec
------------------------------------------------------------------------------
runSimpleFFSTest                           10   4.82 s     482 ms  2.075
runRealFFSTest                             19  2.011 s   105.9 ms  9.447

*/

int main(int argc, char** argv) {
  testing::InitGoogleTest(&argc, argv);
  gflags::ParseCommandLineFlags(&argc, &argv, true);
  auto ret = RUN_ALL_TESTS();
  if (!ret && FLAGS_benchmark) {
    folly::runBenchmarks();
  }
  return ret;
}
