// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "hanging_getter.h"

#include <gtest/gtest.h>

namespace bt_lib_fidl {
namespace {

template <typename T, typename Getter = HangingGetter<T>>
class HangingGetterTestBase : public ::testing::Test {
 public:
  void Watch() {
    getter_.Watch([this](T value) {
      callback_count_++;
      last_value_ = value;
    });
  }

  int callback_count() const { return callback_count_; }
  const std::optional<T>& last_value() const { return last_value_; }

  Getter* getter() { return &getter_; }

 private:
  int callback_count_ = 0;
  std::optional<T> last_value_;
  Getter getter_;
};

using HangingGetterTest = HangingGetterTestBase<bool>;

TEST_F(HangingGetterTest, Armed) {
  EXPECT_FALSE(getter()->armed());
  Watch();
  EXPECT_TRUE(getter()->armed());
}

TEST_F(HangingGetterTest, WatchFailsWhilePending) {
  Watch();
  EXPECT_EQ(0, callback_count());
  Watch();
  EXPECT_EQ(0, callback_count());
}

TEST_F(HangingGetterTest, WatchCallbackDeferredWithoutAValue) {
  Watch();
  EXPECT_EQ(0, callback_count());
  EXPECT_FALSE(last_value().has_value());

  getter()->Set(false);
  EXPECT_EQ(1, callback_count());
  ASSERT_TRUE(last_value().has_value());
  EXPECT_FALSE(*last_value());
}

TEST_F(HangingGetterTest, WatchCallbackRunsRightAwayWithAValue) {
  getter()->Set(false);
  EXPECT_EQ(0, callback_count());
  EXPECT_FALSE(last_value().has_value());

  // Assign the value again to test that the latest value is returned in Watch().
  getter()->Set(true);
  EXPECT_EQ(0, callback_count());
  EXPECT_FALSE(last_value().has_value());
  EXPECT_FALSE(getter()->armed());

  Watch();
  EXPECT_EQ(1, callback_count());
  ASSERT_TRUE(last_value().has_value());
  EXPECT_TRUE(*last_value());

  // Calling Watch() again should succeed and defer the callback.
  Watch();
  EXPECT_EQ(1, callback_count());
}

TEST_F(HangingGetterTest, MultipleWatchersPending) {
  Watch();  // 1
  Watch();  // 2
  Watch();  // 3
  getter()->Set(true);
  EXPECT_EQ(3, callback_count());
  ASSERT_TRUE(last_value().has_value());
  EXPECT_TRUE(*last_value());
  EXPECT_FALSE(getter()->armed());
}

TEST_F(HangingGetterTest, OnlyFirstOfManyWatchersRunsWithAValue) {
  getter()->Set(true);

  // Only the first watch call should result in a callback. The following two are expected to remain
  // pending until a new value gets assigned.
  Watch();  // 1
  Watch();  // 2
  Watch();  // 3
  EXPECT_EQ(1, callback_count());
  ASSERT_TRUE(last_value().has_value());
  EXPECT_TRUE(*last_value());

  EXPECT_TRUE(getter()->armed());
  getter()->Set(false);
  EXPECT_EQ(3, callback_count());
  ASSERT_TRUE(last_value().has_value());
  EXPECT_FALSE(*last_value());
}

TEST_F(HangingGetterTest, WatchClearsExistingValue) {
  getter()->Set(true);
  Watch();
  EXPECT_EQ(1, callback_count());
  ASSERT_TRUE(last_value().has_value());
  EXPECT_TRUE(*last_value());

  // Callback should be deferred.
  Watch();
  EXPECT_EQ(1, callback_count());

  // Test the deferral.
  getter()->Set(true);
  EXPECT_EQ(2, callback_count());
}

TEST_F(HangingGetterTest, Transform) {
  getter()->Set(false);
  getter()->Transform([](bool current) {
    EXPECT_FALSE(current);
    return true;
  });

  Watch();
  EXPECT_EQ(1, callback_count());
  ASSERT_TRUE(last_value().has_value());
  EXPECT_TRUE(*last_value());
}

using HangingVectorGetterTest = HangingGetterTestBase<std::vector<bool>, HangingVectorGetter<bool>>;

TEST_F(HangingVectorGetterTest, AddAndWatch) {
  getter()->Add(false);
  getter()->Add(true);

  Watch();
  EXPECT_EQ(1, callback_count());
  EXPECT_TRUE(last_value().has_value());
  EXPECT_EQ(2u, last_value()->size());
  EXPECT_FALSE((*last_value())[0]);
  EXPECT_TRUE((*last_value())[1]);
}

TEST_F(HangingVectorGetterTest, WatchAndAdd) {
  Watch();
  EXPECT_EQ(0, callback_count());

  getter()->Add(true);
  EXPECT_EQ(1, callback_count());
  EXPECT_TRUE(last_value().has_value());
  EXPECT_EQ(1u, last_value()->size());
  EXPECT_TRUE((*last_value())[0]);
}

}  // namespace
}  // namespace bt_lib_fidl
