/*
 * 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/ScopeGuard.h>
#include <folly/Portability.h>

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

#include <functional>
#include <stdexcept>

using folly::ScopeGuard;
using folly::makeGuard;
using std::vector;

double returnsDouble() {
  return 0.0;
}

class MyFunctor {
 public:
  explicit MyFunctor(int* ptr) : ptr_(ptr) {}

  void operator()() {
    ++*ptr_;
  }

 private:
  int* ptr_;
};

TEST(ScopeGuard, DifferentWaysToBind) {
  {
    // There is implicit conversion from func pointer
    // double (*)() to function<void()>.
    ScopeGuard g = makeGuard(returnsDouble);
  }

  vector<int> v;
  void (vector<int>::*push_back)(int const&) = &vector<int>::push_back;

  v.push_back(1);
  {
    // binding to member function.
    ScopeGuard g = makeGuard(std::bind(&vector<int>::pop_back, &v));
  }
  EXPECT_EQ(0, v.size());

  {
    // bind member function with args. v is passed-by-value!
    ScopeGuard g = makeGuard(std::bind(push_back, v, 2));
  }
  EXPECT_EQ(0, v.size()); // push_back happened on a copy of v... fail!

  // pass in an argument by pointer so to avoid copy.
  {
    ScopeGuard g = makeGuard(std::bind(push_back, &v, 4));
  }
  EXPECT_EQ(1, v.size());

  {
    // pass in an argument by reference so to avoid copy.
    ScopeGuard g = makeGuard(std::bind(push_back, std::ref(v), 4));
  }
  EXPECT_EQ(2, v.size());

  // lambda with a reference to v
  {
    ScopeGuard g = makeGuard([&] { v.push_back(5); });
  }
  EXPECT_EQ(3, v.size());

  // lambda with a copy of v
  {
    ScopeGuard g = makeGuard([v] () mutable { v.push_back(6); });
  }
  EXPECT_EQ(3, v.size());

  // functor object
  int n = 0;
  {
    MyFunctor f(&n);
    ScopeGuard g = makeGuard(f);
  }
  EXPECT_EQ(1, n);

  // temporary functor object
  n = 0;
  {
    ScopeGuard g = makeGuard(MyFunctor(&n));
  }
  EXPECT_EQ(1, n);

  // Use auto instead of ScopeGuard
  n = 2;
  {
    auto g = makeGuard(MyFunctor(&n));
  }
  EXPECT_EQ(3, n);

  // Use const auto& instead of ScopeGuard
  n = 10;
  {
    const auto& g = makeGuard(MyFunctor(&n));
  }
  EXPECT_EQ(11, n);
}

TEST(ScopeGuard, GuardException) {
  EXPECT_DEATH({
    ScopeGuard g = makeGuard([&] {
      throw std::runtime_error("destructors should never throw!");
    });
  },
  "destructors should never throw!"
  );
}

/**
 * Add an integer to a vector iff it was inserted into the
 * db successfuly. Here is a schematic of how you would accomplish
 * this with scope guard.
 */
void testUndoAction(bool failure) {
  vector<int64_t> v;
  { // defines a "mini" scope

    // be optimistic and insert this into memory
    v.push_back(1);

    // The guard is triggered to undo the insertion unless dismiss() is called.
    ScopeGuard guard = makeGuard([&] { v.pop_back(); });

    // Do some action; Use the failure argument to pretend
    // if it failed or succeeded.

    // if there was no failure, dismiss the undo guard action.
    if (!failure) {
      guard.dismiss();
    }
  } // all stack allocated in the mini-scope will be destroyed here.

  if (failure) {
    EXPECT_EQ(0, v.size()); // the action failed => undo insertion
  } else {
    EXPECT_EQ(1, v.size()); // the action succeeded => keep insertion
  }
}

TEST(ScopeGuard, UndoAction) {
  testUndoAction(true);
  testUndoAction(false);
}

/**
 * Sometimes in a try catch block we want to execute a piece of code
 * regardless if an exception happened or not. For example, you want
 * to close a db connection regardless if an exception was thrown during
 * insertion. In Java and other languages there is a finally clause that
 * helps accomplish this:
 *
 *   try {
 *     dbConn.doInsert(sql);
 *   } catch (const DbException& dbe) {
 *     dbConn.recordFailure(dbe);
 *   } catch (const CriticalException& e) {
 *     throw e; // re-throw the exception
 *   } finally {
 *     dbConn.closeConnection(); // executes no matter what!
 *   }
 *
 * We can approximate this behavior in C++ with ScopeGuard.
 */
enum class ErrorBehavior {
  SUCCESS,
  HANDLED_ERROR,
  UNHANDLED_ERROR,
};

void testFinally(ErrorBehavior error) {
  bool cleanupOccurred = false;

  try {
    ScopeGuard guard = makeGuard([&] { cleanupOccurred = true; });

    try {
      if (error == ErrorBehavior::HANDLED_ERROR) {
        throw std::runtime_error("throwing an expected error");
      } else if (error == ErrorBehavior::UNHANDLED_ERROR) {
        throw "never throw raw strings";
      }
    } catch (const std::runtime_error&) {
    }
  } catch (...) {
    // Outer catch to swallow the error for the UNHANDLED_ERROR behavior
  }

  EXPECT_TRUE(cleanupOccurred);
}

TEST(ScopeGuard, TryCatchFinally) {
  testFinally(ErrorBehavior::SUCCESS);
  testFinally(ErrorBehavior::HANDLED_ERROR);
  testFinally(ErrorBehavior::UNHANDLED_ERROR);
}

TEST(ScopeGuard, TEST_SCOPE_EXIT) {
  int x = 0;
  {
    SCOPE_EXIT { ++x; };
    EXPECT_EQ(0, x);
  }
  EXPECT_EQ(1, x);
}

class Foo {
public:
  Foo() {}
  ~Foo() {
    try {
      auto e = std::current_exception();
      int test = 0;
      {
        SCOPE_EXIT { ++test; };
        EXPECT_EQ(0, test);
      }
      EXPECT_EQ(1, test);
    } catch (const std::exception& ex) {
      LOG(FATAL) << "Unexpected exception: " << ex.what();
    }
  }
};

TEST(ScopeGuard, TEST_SCOPE_FAILURE2) {
  try {
    Foo f;
    throw std::runtime_error("test");
  } catch (...) {
  }
}

void testScopeFailAndScopeSuccess(ErrorBehavior error, bool expectFail) {
  bool scopeFailExecuted = false;
  bool scopeSuccessExecuted = false;

  try {
    SCOPE_FAIL { scopeFailExecuted = true; };
    SCOPE_SUCCESS { scopeSuccessExecuted = true; };

    try {
      if (error == ErrorBehavior::HANDLED_ERROR) {
        throw std::runtime_error("throwing an expected error");
      } else if (error == ErrorBehavior::UNHANDLED_ERROR) {
        throw "never throw raw strings";
      }
    } catch (const std::runtime_error&) {
    }
  } catch (...) {
    // Outer catch to swallow the error for the UNHANDLED_ERROR behavior
  }

  EXPECT_EQ(expectFail, scopeFailExecuted);
  EXPECT_EQ(!expectFail, scopeSuccessExecuted);
}

TEST(ScopeGuard, TEST_SCOPE_FAIL_AND_SCOPE_SUCCESS) {
  testScopeFailAndScopeSuccess(ErrorBehavior::SUCCESS, false);
  testScopeFailAndScopeSuccess(ErrorBehavior::HANDLED_ERROR, false);
  testScopeFailAndScopeSuccess(ErrorBehavior::UNHANDLED_ERROR, true);
}

TEST(ScopeGuard, TEST_SCOPE_SUCCESS_THROW) {
  auto lambda = []() {
    SCOPE_SUCCESS { throw std::runtime_error("ehm"); };
  };
  EXPECT_THROW(lambda(), std::runtime_error);
}

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