// Copyright 2018 The Chromium 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 "services/audio/test/mock_group_coordinator.h"

#include "base/stl_util.h"
#include "base/unguessable_token.h"
#include "services/audio/test/mock_group_member.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using base::UnguessableToken;

using testing::AtLeast;
using testing::NiceMock;
using testing::ReturnRef;
using testing::Sequence;
using testing::StrictMock;
using testing::_;

namespace audio {

class TestGroupCoordinator : public GroupCoordinator<MockGroupMember> {
 public:
  const std::vector<MockGroupMember*>& GetCurrentMembers(
      const base::UnguessableToken& group_id) const {
    return GetCurrentMembersUnsafe(group_id);
  }
};

namespace {

class MockGroupObserver : public TestGroupCoordinator::Observer {
 public:
  MockGroupObserver() = default;
  ~MockGroupObserver() override = default;

  MOCK_METHOD1(OnMemberJoinedGroup, void(MockGroupMember* member));
  MOCK_METHOD1(OnMemberLeftGroup, void(MockGroupMember* member));

 private:
  DISALLOW_COPY_AND_ASSIGN(MockGroupObserver);
};

TEST(GroupCoordinatorTest, NeverUsed) {
  TestGroupCoordinator coordinator;
}

TEST(GroupCoordinatorTest, RegistersMembersInSameGroup) {
  const UnguessableToken group_id = UnguessableToken::Create();
  StrictMock<MockGroupMember> member1;
  StrictMock<MockGroupMember> member2;

  // An observer should see each member join and leave the group once.
  StrictMock<MockGroupObserver> observer;
  Sequence join_leave_sequence;
  EXPECT_CALL(observer, OnMemberJoinedGroup(&member1))
      .InSequence(join_leave_sequence);
  EXPECT_CALL(observer, OnMemberJoinedGroup(&member2))
      .InSequence(join_leave_sequence);
  EXPECT_CALL(observer, OnMemberLeftGroup(&member1))
      .InSequence(join_leave_sequence);
  EXPECT_CALL(observer, OnMemberLeftGroup(&member2))
      .InSequence(join_leave_sequence);

  TestGroupCoordinator coordinator;
  coordinator.AddObserver(group_id, &observer);
  coordinator.RegisterMember(group_id, &member1);
  coordinator.RegisterMember(group_id, &member2);

  const std::vector<MockGroupMember*>& members =
      coordinator.GetCurrentMembers(group_id);
  EXPECT_EQ(2u, members.size());
  EXPECT_TRUE(base::ContainsValue(members, &member1));
  EXPECT_TRUE(base::ContainsValue(members, &member2));
  EXPECT_TRUE(
      coordinator.GetCurrentMembers(UnguessableToken::Create()).empty());

  coordinator.UnregisterMember(group_id, &member1);
  coordinator.UnregisterMember(group_id, &member2);
  EXPECT_TRUE(coordinator.GetCurrentMembers(group_id).empty());

  coordinator.RemoveObserver(group_id, &observer);
  EXPECT_TRUE(coordinator.GetCurrentMembers(group_id).empty());
}

TEST(GroupCoordinatorTest, RegistersMembersInDifferentGroups) {
  const UnguessableToken group_id_a = UnguessableToken::Create();
  StrictMock<MockGroupMember> member_a_1;
  StrictMock<MockGroupMember> member_a_2;

  StrictMock<MockGroupObserver> observer_a;
  Sequence join_leave_sequence_a;
  EXPECT_CALL(observer_a, OnMemberJoinedGroup(&member_a_1))
      .InSequence(join_leave_sequence_a);
  EXPECT_CALL(observer_a, OnMemberJoinedGroup(&member_a_2))
      .InSequence(join_leave_sequence_a);
  EXPECT_CALL(observer_a, OnMemberLeftGroup(&member_a_1))
      .InSequence(join_leave_sequence_a);
  EXPECT_CALL(observer_a, OnMemberLeftGroup(&member_a_2))
      .InSequence(join_leave_sequence_a);

  const UnguessableToken group_id_b = UnguessableToken::Create();
  StrictMock<MockGroupMember> member_b_1;

  StrictMock<MockGroupObserver> observer_b;
  Sequence join_leave_sequence_b;
  EXPECT_CALL(observer_b, OnMemberJoinedGroup(&member_b_1))
      .InSequence(join_leave_sequence_b);
  EXPECT_CALL(observer_b, OnMemberLeftGroup(&member_b_1))
      .InSequence(join_leave_sequence_b);

  TestGroupCoordinator coordinator;
  coordinator.AddObserver(group_id_a, &observer_a);
  coordinator.AddObserver(group_id_b, &observer_b);
  coordinator.RegisterMember(group_id_a, &member_a_1);
  coordinator.RegisterMember(group_id_b, &member_b_1);
  coordinator.RegisterMember(group_id_a, &member_a_2);
  const std::vector<MockGroupMember*>& members_a =
      coordinator.GetCurrentMembers(group_id_a);
  EXPECT_EQ(2u, members_a.size());
  EXPECT_TRUE(base::ContainsValue(members_a, &member_a_1));
  EXPECT_TRUE(base::ContainsValue(members_a, &member_a_2));
  EXPECT_EQ(std::vector<MockGroupMember*>({&member_b_1}),
            coordinator.GetCurrentMembers(group_id_b));
  EXPECT_TRUE(
      coordinator.GetCurrentMembers(UnguessableToken::Create()).empty());

  coordinator.UnregisterMember(group_id_a, &member_a_1);
  EXPECT_EQ(std::vector<MockGroupMember*>({&member_a_2}),
            coordinator.GetCurrentMembers(group_id_a));

  coordinator.UnregisterMember(group_id_b, &member_b_1);
  EXPECT_TRUE(coordinator.GetCurrentMembers(group_id_b).empty());

  coordinator.UnregisterMember(group_id_a, &member_a_2);
  EXPECT_TRUE(coordinator.GetCurrentMembers(group_id_a).empty());

  coordinator.RemoveObserver(group_id_a, &observer_a);
  coordinator.RemoveObserver(group_id_b, &observer_b);
  EXPECT_TRUE(coordinator.GetCurrentMembers(group_id_a).empty());
  EXPECT_TRUE(coordinator.GetCurrentMembers(group_id_b).empty());
}

TEST(GroupCoordinatorTest, TracksMembersWithoutAnObserverPresent) {
  const UnguessableToken group_id = UnguessableToken::Create();
  StrictMock<MockGroupMember> member1;
  StrictMock<MockGroupMember> member2;

  TestGroupCoordinator coordinator;
  coordinator.RegisterMember(group_id, &member1);
  coordinator.RegisterMember(group_id, &member2);

  const std::vector<MockGroupMember*>& members =
      coordinator.GetCurrentMembers(group_id);
  EXPECT_EQ(2u, members.size());
  EXPECT_TRUE(base::ContainsValue(members, &member1));
  EXPECT_TRUE(base::ContainsValue(members, &member2));
  EXPECT_TRUE(
      coordinator.GetCurrentMembers(UnguessableToken::Create()).empty());

  coordinator.UnregisterMember(group_id, &member1);
  coordinator.UnregisterMember(group_id, &member2);
  EXPECT_TRUE(coordinator.GetCurrentMembers(group_id).empty());
}

TEST(GroupCoordinatorTest, NotifiesOnlyWhileObserving) {
  const UnguessableToken group_id = UnguessableToken::Create();
  StrictMock<MockGroupMember> member1;
  StrictMock<MockGroupMember> member2;

  // The observer will only be around at the time when member2 joins the group
  // and when member1 leaves the group.
  StrictMock<MockGroupObserver> observer;
  Sequence join_leave_sequence;
  EXPECT_CALL(observer, OnMemberJoinedGroup(&member1)).Times(0);
  EXPECT_CALL(observer, OnMemberJoinedGroup(&member2))
      .InSequence(join_leave_sequence);
  EXPECT_CALL(observer, OnMemberLeftGroup(&member1))
      .InSequence(join_leave_sequence);
  EXPECT_CALL(observer, OnMemberLeftGroup(&member2)).Times(0);

  TestGroupCoordinator coordinator;
  coordinator.RegisterMember(group_id, &member1);
  EXPECT_EQ(std::vector<MockGroupMember*>({&member1}),
            coordinator.GetCurrentMembers(group_id));

  coordinator.AddObserver(group_id, &observer);
  coordinator.RegisterMember(group_id, &member2);
  const std::vector<MockGroupMember*>& members =
      coordinator.GetCurrentMembers(group_id);
  EXPECT_EQ(2u, members.size());
  EXPECT_TRUE(base::ContainsValue(members, &member1));
  EXPECT_TRUE(base::ContainsValue(members, &member2));

  coordinator.UnregisterMember(group_id, &member1);
  EXPECT_EQ(std::vector<MockGroupMember*>({&member2}),
            coordinator.GetCurrentMembers(group_id));

  coordinator.RemoveObserver(group_id, &observer);
  EXPECT_EQ(std::vector<MockGroupMember*>({&member2}),
            coordinator.GetCurrentMembers(group_id));

  coordinator.UnregisterMember(group_id, &member2);
  EXPECT_TRUE(coordinator.GetCurrentMembers(group_id).empty());
}

}  // namespace
}  // namespace audio
