// Copyright 2018 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 "lib/fidl/cpp/interface_ptr_set.h"

#include <gtest/gtest.h>

#include "lib/fidl/cpp/binding.h"
#include "lib/fidl/cpp/test/async_loop_for_test.h"
#include "lib/fidl/cpp/test/frobinator_impl.h"

namespace fidl {
namespace {

class BoundFrobinatorImpl : public test::FrobinatorImpl {
 public:
  BoundFrobinatorImpl() : binding_(this) {}

  Binding<fidl::test::frobinator::Frobinator>& binding() { return binding_; }

 private:
  Binding<fidl::test::frobinator::Frobinator> binding_;
};

TEST(InterfacePtrSet, Trivial) { InterfacePtrSet<fidl::test::frobinator::Frobinator> ptr_set; }

TEST(InterfacePtrSet, Control) {
  constexpr size_t kCount = 10;

  fidl::test::frobinator::FrobinatorPtr ptrs[kCount];
  BoundFrobinatorImpl impls[kCount];

  InterfacePtrSet<fidl::test::frobinator::Frobinator> ptr_set;

  fidl::test::AsyncLoopForTest loop;

  for (size_t i = 0; i < kCount; ++i)
    impls[i].binding().Bind(ptrs[i].NewRequest());

  EXPECT_EQ(0u, ptr_set.size());
  for (size_t i = 0; i < kCount; ++i)
    ptr_set.AddInterfacePtr(std::move(ptrs[i]));
  EXPECT_EQ(kCount, ptr_set.size());

  for (const auto& impl : impls)
    EXPECT_TRUE(impl.frobs.empty());

  size_t iter_count = 0;
  for (const auto& ptr : ptr_set.ptrs()) {
    ++iter_count;
    (*ptr)->Frob("three");
  }

  EXPECT_EQ(kCount, iter_count);

  loop.RunUntilIdle();

  for (const auto& impl : impls)
    EXPECT_EQ(1u, impl.frobs.size());

  for (size_t i = 0; i < kCount / 2; ++i)
    impls[i].binding().Unbind();

  EXPECT_EQ(kCount, ptr_set.size());
  loop.RunUntilIdle();
  EXPECT_EQ(kCount / 2, ptr_set.size());

  for (const auto& ptr : ptr_set.ptrs())
    (*ptr)->Frob("two");

  loop.RunUntilIdle();

  for (size_t i = 0; i < kCount; ++i) {
    size_t expected = (i < kCount / 2 ? 1 : 2);
    EXPECT_EQ(expected, impls[i].frobs.size());
  }

  ptr_set.CloseAll();

  EXPECT_EQ(0u, ptr_set.size());

  for (const auto& ptr : ptr_set.ptrs())
    (*ptr)->Frob("three");

  loop.RunUntilIdle();

  for (size_t i = 0; i < kCount; ++i) {
    size_t expected = (i < kCount / 2 ? 1 : 2);
    EXPECT_EQ(expected, impls[i].frobs.size());
  }
}

}  // namespace
}  // namespace fidl
