// Copyright 2021 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 <queue>

#include "src/connectivity/network/mdns/service/services/mdns_deprecated_service_impl.h"
#include "src/lib/testing/loop_fixture/test_loop_fixture.h"

namespace mdns {
namespace test {

class ResponderPublisherTest : public gtest::TestLoopFixture,
                               public fuchsia::net::mdns::PublicationResponder {
 public:
  struct OnPublicationCall {
    OnPublicationCall(fuchsia::net::mdns::PublicationCause publication_cause,
                      fidl::StringPtr subtype,
                      std::vector<fuchsia::net::IpAddress> source_addresses,
                      OnPublicationCallback callback)
        : publication_cause_(publication_cause),
          subtype_(subtype),
          source_addresses_(std::move(source_addresses)),
          callback_(std::move(callback)) {}

    fuchsia::net::mdns::PublicationCause publication_cause_;
    fidl::StringPtr subtype_;
    std::vector<fuchsia::net::IpAddress> source_addresses_;
    OnPublicationCallback callback_;
  };

  ResponderPublisherTest() : binding_(this) {}

  ~ResponderPublisherTest() override = default;

  void Bind(fidl::InterfaceRequest<fuchsia::net::mdns::PublicationResponder> request) {
    binding_.Bind(std::move(request));
  }

  std::queue<OnPublicationCall>& on_publication_calls() { return on_publication_calls_; }

  // fuchsia::net::mdns::PublicationResponder implementation.
  void OnPublication(fuchsia::net::mdns::PublicationCause publication_cause,
                     fidl::StringPtr subtype, std::vector<fuchsia::net::IpAddress> source_addresses,
                     OnPublicationCallback callback) override {
    on_publication_calls_.emplace(publication_cause, subtype, std::move(source_addresses),
                                  std::move(callback));
  }

 private:
  fidl::Binding<fuchsia::net::mdns::PublicationResponder> binding_;
  std::queue<OnPublicationCall> on_publication_calls_;
};

// Tests that flow control of |OnPublication| calls works properly.
TEST_F(ResponderPublisherTest, FlowControl) {
  fuchsia::net::mdns::PublicationResponderPtr responder;
  Bind(responder.NewRequest());

  bool deleter_called = false;
  MdnsDeprecatedServiceImpl::ResponderPublisher under_test(
      std::move(responder),
      [](fuchsia::net::mdns::Publisher_PublishServiceInstance_Result result) {},
      [&deleter_called]() { deleter_called = true; });

  // Ask the publisher for a publication and expect that the request is forwarded over FIDL.
  under_test.GetPublication(PublicationCause::kAnnouncement, "1", {},
                            [](std::unique_ptr<Mdns::Publication> publication) {});
  RunLoopUntilIdle();
  EXPECT_EQ(1u, on_publication_calls().size());

  // Ask the publisher for a second publication and expect that this one is also forwarded.
  under_test.GetPublication(PublicationCause::kAnnouncement, "2", {},
                            [](std::unique_ptr<Mdns::Publication> publication) {});
  RunLoopUntilIdle();
  EXPECT_EQ(2u, on_publication_calls().size());

  // Ask the publisher for a third publication. Expect that it's not forwarded yet, because we
  // haven't responded to either of the first two.
  under_test.GetPublication(PublicationCause::kAnnouncement, "3", {},
                            [](std::unique_ptr<Mdns::Publication> publication) {});
  RunLoopUntilIdle();
  EXPECT_EQ(2u, on_publication_calls().size());

  // Respond to the first request and expect the third request to be forwarded.
  EXPECT_EQ("1", on_publication_calls().front().subtype_);
  on_publication_calls().front().callback_(nullptr);
  on_publication_calls().pop();
  EXPECT_EQ(1u, on_publication_calls().size());
  RunLoopUntilIdle();
  EXPECT_EQ(2u, on_publication_calls().size());

  // Ask the publisher for a fourth publication. Expect that it's not forwarded yet, because we
  // haven't responded to either of the second and third requests.
  under_test.GetPublication(PublicationCause::kAnnouncement, "4", {},
                            [](std::unique_ptr<Mdns::Publication> publication) {});
  RunLoopUntilIdle();
  EXPECT_EQ(2u, on_publication_calls().size());

  // Respond to the second request and expect the fourth request to be forwarded.
  EXPECT_EQ("2", on_publication_calls().front().subtype_);
  on_publication_calls().front().callback_(nullptr);
  on_publication_calls().pop();
  EXPECT_EQ(1u, on_publication_calls().size());
  RunLoopUntilIdle();
  EXPECT_EQ(2u, on_publication_calls().size());

  // Respond to the third and fourth requests.
  EXPECT_EQ("3", on_publication_calls().front().subtype_);
  on_publication_calls().front().callback_(nullptr);
  on_publication_calls().pop();
  EXPECT_EQ("4", on_publication_calls().front().subtype_);
  on_publication_calls().front().callback_(nullptr);
  on_publication_calls().pop();
  RunLoopUntilIdle();
  EXPECT_EQ(0u, on_publication_calls().size());

  EXPECT_FALSE(deleter_called);
}

}  // namespace test
}  // namespace mdns
