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

#include <folly/futures/Future.h>
#include <folly/futures/InlineExecutor.h>
#include <folly/futures/ManualExecutor.h>
#include <folly/futures/QueuedImmediateExecutor.h>
#include <folly/Baton.h>

using namespace folly;

TEST(ManualExecutor, runIsStable) {
  ManualExecutor x;
  size_t count = 0;
  auto f1 = [&]() { count++; };
  auto f2 = [&]() { x.add(f1); x.add(f1); };
  x.add(f2);
  x.run();
}

TEST(ManualExecutor, scheduleDur) {
  ManualExecutor x;
  size_t count = 0;
  std::chrono::milliseconds dur {10};
  x.schedule([&]{ count++; }, dur);
  EXPECT_EQ(count, 0);
  x.run();
  EXPECT_EQ(count, 0);
  x.advance(dur/2);
  EXPECT_EQ(count, 0);
  x.advance(dur/2);
  EXPECT_EQ(count, 1);
}

TEST(ManualExecutor, clockStartsAt0) {
  ManualExecutor x;
  EXPECT_EQ(x.now(), x.now().min());
}

TEST(ManualExecutor, scheduleAbs) {
  ManualExecutor x;
  size_t count = 0;
  x.scheduleAt([&]{ count++; }, x.now() + std::chrono::milliseconds(10));
  EXPECT_EQ(count, 0);
  x.advance(std::chrono::milliseconds(10));
  EXPECT_EQ(count, 1);
}

TEST(ManualExecutor, advanceTo) {
  ManualExecutor x;
  size_t count = 0;
  x.scheduleAt([&]{ count++; }, std::chrono::steady_clock::now());
  EXPECT_EQ(count, 0);
  x.advanceTo(std::chrono::steady_clock::now());
  EXPECT_EQ(count, 1);
}

TEST(ManualExecutor, advanceBack) {
  ManualExecutor x;
  size_t count = 0;
  x.advance(std::chrono::microseconds(5));
  x.schedule([&]{ count++; }, std::chrono::microseconds(6));
  EXPECT_EQ(count, 0);
  x.advanceTo(x.now() - std::chrono::microseconds(1));
  EXPECT_EQ(count, 0);
}

TEST(ManualExecutor, advanceNeg) {
  ManualExecutor x;
  size_t count = 0;
  x.advance(std::chrono::microseconds(5));
  x.schedule([&]{ count++; }, std::chrono::microseconds(6));
  EXPECT_EQ(count, 0);
  x.advance(std::chrono::microseconds(-1));
  EXPECT_EQ(count, 0);
}

TEST(ManualExecutor, waitForDoesNotDeadlock) {
  ManualExecutor east, west;
  folly::Baton<> baton;
  auto f = makeFuture()
    .via(&east)
    .then([](Try<Unit>){ return makeFuture(); })
    .via(&west);
  std::thread t([&]{
    baton.post();
    west.waitFor(f);
  });
  baton.wait();
  east.run();
  t.join();
}

TEST(Executor, InlineExecutor) {
  InlineExecutor x;
  size_t counter = 0;
  x.add([&]{
    x.add([&]{
      EXPECT_EQ(counter, 0);
      counter++;
    });
    EXPECT_EQ(counter, 1);
    counter++;
  });
  EXPECT_EQ(counter, 2);
}

TEST(Executor, QueuedImmediateExecutor) {
  QueuedImmediateExecutor x;
  size_t counter = 0;
  x.add([&]{
    x.add([&]{
      EXPECT_EQ(1, counter);
      counter++;
    });
    EXPECT_EQ(0, counter);
    counter++;
  });
  EXPECT_EQ(2, counter);
}

TEST(Executor, Runnable) {
  InlineExecutor x;
  size_t counter = 0;
  struct Runnable {
    std::function<void()> fn;
    void operator()() { fn(); }
  };
  Runnable f;
  f.fn = [&]{ counter++; };
  x.add(f);
  EXPECT_EQ(counter, 1);
}

TEST(Executor, RunnablePtr) {
  InlineExecutor x;
  struct Runnable {
    std::function<void()> fn;
    void operator()() { fn(); }
  };
  size_t counter = 0;
  auto fnp = std::make_shared<Runnable>();
  fnp->fn = [&]{ counter++; };
  x.addPtr(fnp);
  EXPECT_EQ(counter, 1);
}

TEST(Executor, ThrowableThen) {
  InlineExecutor x;
  auto f = Future<Unit>().via(&x).then([](){
    throw std::runtime_error("Faildog");
  });
  EXPECT_THROW(f.value(), std::exception);
}

class CrappyExecutor : public Executor {
 public:
  void add(Func f) override {
    throw std::runtime_error("bad");
  }
};

TEST(Executor, CrappyExecutor) {
  CrappyExecutor x;
  bool flag = false;
  auto f = folly::via(&x).onError([&](std::runtime_error& e) {
    EXPECT_STREQ("bad", e.what());
    flag = true;
  });
  EXPECT_TRUE(flag);
}

/* Exception should break out of Executor::run() even in Future destroyed */
TEST(Executor, exceptionsOnAbandonedFutures)
{
    ManualExecutor x;
    Promise<unsigned> p;

    {
        p.getFuture().via(&x)
            .then([&] (Try<unsigned>&& i) {
                    i.value();
                })
            .onErrorThrowIn(&x);
    }

    p.setException(std::logic_error("fubar"));

    EXPECT_THROW(while (x.run()) {}, std::logic_error);
}

/* Implementation of onErrorThrowIn() shall not interfere with onError()'s behavior */
TEST(Executor, execeptionsOnAbandondedFuturesOnError)
{
    ManualExecutor x;
    Promise<unsigned> p;
    unsigned k = 0;

    {
        auto f = p.getFuture().via(&x)
            .then([&] (unsigned i) { EXPECT_TRUE(false); })
            .onError([&] (std::logic_error& e) { ++k; });
    }

    p.setException(std::logic_error("fubar"));

    while (x.run()) {}

    EXPECT_EQ(1, k);
}
