// 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 "chrome/browser/chromeos/printing/zeroconf_printer_detector.h"

#include <algorithm>
#include <functional>
#include <random>
#include <set>
#include <string>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/stl_util.h"
#include "base/strings/strcat.h"
#include "base/strings/stringprintf.h"
#include "base/test/scoped_task_environment.h"
#include "base/time/time.h"
#include "chrome/browser/local_discovery/service_discovery_device_lister.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace chromeos {
namespace {

using local_discovery::ServiceDescription;
using local_discovery::ServiceDiscoveryDeviceLister;

// Determine basic printer attributes deterministically but pseudorandomly based
// on the printer name.  The exact values returned here are not really
// important, the important parts are that there's variety based on the name,
// and it's deterministic.

// Should this printer provide usb_MFG and usb_MDL fields?
bool GetUsbFor(const std::string& name) {
  return std::hash<std::string>()(name) & 1;
}

// Get an IP address for this printer.  The returned address may be IPv4 or IPv6
net::IPAddress GetIPAddressFor(const std::string& name) {
  std::mt19937 rng(std::hash<std::string>()(name));
  if (rng() & 1) {
    // Give an IPv4 address.
    return net::IPAddress(rng(), rng(), rng(), rng());
  } else {
    // Give an IPv6 address.
    return net::IPAddress(rng(), rng(), rng(), rng(), rng(), rng(), rng(),
                          rng(), rng(), rng(), rng(), rng(), rng(), rng(),
                          rng(), rng());
  }
}

int GetPortFor(const std::string& name) {
  return (std::hash<std::string>()(name) % 1000) + 1;
}

// Bitfield flags for MakeExpectedPrinter()
int kFlagSSL = 0x1;   // Use ipps, not ipp.
int kFlagIPPE = 0x2;  // Printer can be autoconfigured with IPP-Everywhere

// This corresponds to FakeServiceDeviceLister::MakeServiceDescription.  Given
// the same name (and the correct ssl/ippe flags based on the service type) this
// generates the DetectedPrinter record we expect from ZeroconfPrinterDectector
// when it gets that ServiceDescription.  This needs to be kept in sync with
// FakeServiceDeviceLister::MakeServiceDescription.
PrinterDetector::DetectedPrinter MakeExpectedPrinter(const std::string& name,
                                                     int flags) {
  PrinterDetector::DetectedPrinter detected;
  Printer& printer = detected.printer;
  net::IPAddress ip_address = GetIPAddressFor(name);
  int port = GetPortFor(name);
  bool ssl = flags & kFlagSSL;
  printer.set_effective_uri(
      base::StringPrintf("ipp%s://%s:%d/%s_rp", ssl ? "s" : "",
                         ip_address.ToString().c_str(), port, name.c_str()));
  printer.set_uri(base::StringPrintf("ipp%s://%s.local:%d/%s_rp",
                                     ssl ? "s" : "", name.c_str(), port,
                                     name.c_str()));

  printer.set_uuid(base::StrCat({name, "_UUID"}));
  printer.set_display_name(base::StrCat({name, "_ty"}));
  printer.set_description(base::StrCat({name, "_note"}));
  printer.set_make_and_model(base::StrCat({name, "_product"}));
  detected.ppd_search_data.make_and_model.push_back(printer.display_name());
  detected.ppd_search_data.make_and_model.push_back(printer.make_and_model());
  if (GetUsbFor(name)) {
    // We should get an effective make and model guess from the usb fields
    // if they exist.
    detected.ppd_search_data.make_and_model.push_back(
        base::StrCat({name, "_usb_MFG ", name, "_usb_MDL"}));
  }

  if (flags & kFlagIPPE) {
    printer.mutable_ppd_reference()->autoconf = true;
  }
  return detected;
}

// This is a thin wrapper around Delegate that defers callbacks until
// the actual delegate is initialized, then calls all deferred callbacks.  Once
// the actual delegate is initialized, this just becomes a simple passthrough.
class DeferringDelegate : public ServiceDiscoveryDeviceLister::Delegate {
 public:
  void OnDeviceChanged(const std::string& service_type,
                       bool added,
                       const ServiceDescription& service_description) override {
    if (actual_) {
      actual_->OnDeviceChanged(service_type, added, service_description);
    } else {
      deferred_callbacks_.push_back(base::BindOnce(
          &DeferringDelegate::OnDeviceChanged, base::Unretained(this),
          service_type, added, service_description));
    }
  }
  // Not guaranteed to be called after OnDeviceChanged.
  void OnDeviceRemoved(const std::string& service_type,
                       const std::string& service_name) override {
    if (actual_) {
      actual_->OnDeviceRemoved(service_type, service_name);
    } else {
      deferred_callbacks_.push_back(
          base::BindOnce(&DeferringDelegate::OnDeviceRemoved,
                         base::Unretained(this), service_type, service_name));
    }
  }

  void OnDeviceCacheFlushed(const std::string& service_type) override {
    if (actual_) {
      actual_->OnDeviceCacheFlushed(service_type);
    } else {
      deferred_callbacks_.push_back(
          base::BindOnce(&DeferringDelegate::OnDeviceCacheFlushed,
                         base::Unretained(this), service_type));
    }
  }

  void SetActual(ServiceDiscoveryDeviceLister::Delegate* actual) {
    CHECK(!actual_);
    actual_ = actual;
    for (auto& cb : deferred_callbacks_) {
      std::move(cb).Run();
    }
    deferred_callbacks_.clear();
  }

 private:
  std::vector<base::OnceCallback<void()>> deferred_callbacks_;
  ServiceDiscoveryDeviceLister::Delegate* actual_ = nullptr;
};

// A fake ServiceDiscoveryDeviceLister.  This provides an implementation
// of ServiceDiscoveryDeviceLister that tests can use to trigger addition
// and removal of devices.
//
// There's some hackery here to handle constructor order constraints.  There's a
// circular dependency in that ZeroconfPrinterDetector (which is a device lister
// delegate) needs its device lister set to be supplied at construction time,
// and each device lister needs to know about its delegate for callbacks.  Thus
// we use DeferringDelegate to queue callbacks triggered before we have the
// delegate reference in this class, and invoke those queued callbacks when the
// Delegate is set.
class FakeServiceDiscoveryDeviceLister : public ServiceDiscoveryDeviceLister {
 public:
  FakeServiceDiscoveryDeviceLister(base::TaskRunner* task_runner,
                                   const std::string& service_type)
      : task_runner_(task_runner), service_type_(service_type) {}

  ~FakeServiceDiscoveryDeviceLister() override = default;

  // The only thing we care about with Start() is that it's called before
  // DiscoverNewDevices.
  void Start() override {
    if (start_called_) {
      ADD_FAILURE() << "Start called multiple times";
    }
    start_called_ = true;
  }

  // When DiscoverNewDevices is called, all updates we've queued up until this
  // point are invoked.
  void DiscoverNewDevices() override {
    if (!start_called_) {
      ADD_FAILURE() << "DiscoverNewDevices called before Start";
    }
    discovery_started_ = true;
    for (const auto& update : queued_updates_) {
      SendUpdate(update);
    }
    queued_updates_.clear();
  }

  const std::string& service_type() const override { return service_type_; }

  void SetDelegate(ServiceDiscoveryDeviceLister::Delegate* delegate) {
    deferring_delegate_.SetActual(delegate);
  }

  // Announce a new service or update it if we've seen it before and already
  // announced it.  If discovery hasn't started yet, queue the description
  // to be sent when discovery is started.
  void Announce(const std::string& name) {
    ServiceDescription description = MakeServiceDescription(name);
    if (!discovery_started_) {
      queued_updates_.push_back(description);
    } else {
      SendUpdate(description);
    }
  }

  void Remove(const std::string& name) {
    std::string service_name = base::StrCat({name, ".", service_type_});
    announced_services_.erase(service_name);
    CHECK(task_runner_->PostTask(
        FROM_HERE,
        base::BindOnce(&ServiceDiscoveryDeviceLister::Delegate::OnDeviceRemoved,
                       base::Unretained(&deferring_delegate_), service_type_,
                       service_name)));
  }

  // Simulate an event that clears downstream caches and the lister.
  void Clear() {
    announced_services_.clear();
    discovery_started_ = false;
    CHECK(task_runner_->PostTask(
        FROM_HERE,
        base::BindOnce(
            &ServiceDiscoveryDeviceLister::Delegate::OnDeviceCacheFlushed,
            base::Unretained(&deferring_delegate_), service_type_)));
  }

  // Create a deterministic ServiceDescription based on the name and this
  // lister's service_type.  See the note on MakeExpectedPrinter, above.  This
  // is a member function instead of a free function because the service_type_
  // impacts some of the fields.  This must be kept in sync with
  // MakeExpectedPrinter.
  ServiceDescription MakeServiceDescription(const std::string& name) {
    ServiceDescription sd;
    sd.service_name = base::StrCat({name, ".", service_type_});
    sd.metadata.push_back(base::StrCat({"ty=", name, "_ty"}));
    sd.metadata.push_back(base::StrCat({"product=(", name, "_product)"}));
    if (GetUsbFor(name)) {
      sd.metadata.push_back(base::StrCat({"usb_MFG=", name, "_usb_MFG"}));
      sd.metadata.push_back(base::StrCat({"usb_MDL=", name, "_usb_MDL"}));
    }
    sd.metadata.push_back(base::StrCat({"rp=", name, "_rp"}));
    sd.metadata.push_back(base::StrCat({"note=", name, "_note"}));
    sd.metadata.push_back(base::StrCat({"UUID=", name, "_UUID"}));
    sd.address.set_host(base::StrCat({name, ".local"}));
    sd.ip_address = GetIPAddressFor(name);
    sd.address.set_port(GetPortFor(name));
    return sd;
  }

  bool discovery_started() { return discovery_started_; }

 private:
  void SendUpdate(const ServiceDescription& description) {
    bool is_new;
    if (!base::ContainsKey(announced_services_, description.service_name)) {
      is_new = true;
      announced_services_.insert(description.service_name);
    } else {
      is_new = false;
    }
    CHECK(task_runner_->PostTask(
        FROM_HERE,
        base::BindOnce(&ServiceDiscoveryDeviceLister::Delegate::OnDeviceChanged,
                       base::Unretained(&deferring_delegate_), service_type_,
                       is_new, description)));
  }
  base::TaskRunner* task_runner_;

  // Services which have previously posted an update, and therefore are no
  // longer 'new' for the purposes of the OnDeviceChanged callback.
  std::set<std::string> announced_services_;

  // Updates added to the class before discovery started.
  std::vector<ServiceDescription> queued_updates_;

  // Has Start() been called?
  bool start_called_ = false;

  // Has DiscoverNewDevices been called?
  bool discovery_started_ = false;

  std::string service_type_;
  DeferringDelegate deferring_delegate_;
};

class ZeroconfPrinterDetectorTest : public testing::Test,
                                    public PrinterDetector::Observer {
 public:
  ZeroconfPrinterDetectorTest() {
    auto* runner = scoped_task_environment_.GetMainThreadTaskRunner().get();
    auto ipp_lister = std::make_unique<FakeServiceDiscoveryDeviceLister>(
        runner, ZeroconfPrinterDetector::kIppServiceName);
    ipp_lister_ = ipp_lister.get();
    auto ipps_lister = std::make_unique<FakeServiceDiscoveryDeviceLister>(
        runner, ZeroconfPrinterDetector::kIppsServiceName);
    ipps_lister_ = ipps_lister.get();
    auto ippe_lister = std::make_unique<FakeServiceDiscoveryDeviceLister>(
        runner, ZeroconfPrinterDetector::kIppEverywhereServiceName);
    ippe_lister_ = ippe_lister.get();
    auto ippse_lister = std::make_unique<FakeServiceDiscoveryDeviceLister>(
        runner, ZeroconfPrinterDetector::kIppsEverywhereServiceName);
    ippse_lister_ = ippse_lister.get();

    listers_[ZeroconfPrinterDetector::kIppServiceName] = std::move(ipp_lister);
    listers_[ZeroconfPrinterDetector::kIppsServiceName] =
        std::move(ipps_lister);
    listers_[ZeroconfPrinterDetector::kIppEverywhereServiceName] =
        std::move(ippe_lister);
    listers_[ZeroconfPrinterDetector::kIppsEverywhereServiceName] =
        std::move(ippse_lister);
  }
  ~ZeroconfPrinterDetectorTest() override = default;

  void CreateDetector() {
    detector_ = ZeroconfPrinterDetector::CreateForTesting(&listers_);
    // The previously allocated listers_ are swapped into the detector_, and so
    // the unique_ptr values of the listers_ map are no longer valid at this
    // point.  The ipp[se]_lister_ raw pointers are kept as seperate members to
    // keep the lister fakes accessible after ownership is transferred into the
    // detector.
    listers_.clear();
    detector_->AddObserver(this);
    ipp_lister_->SetDelegate(detector_.get());
    ipps_lister_->SetDelegate(detector_.get());
    ippe_lister_->SetDelegate(detector_.get());
    ippse_lister_->SetDelegate(detector_.get());
  }

  // Expect that the most up-to-date results from the detector match those
  // in printers.
  void ExpectPrintersAre(
      const std::vector<PrinterDetector::DetectedPrinter>& printers) {
    // The last observer callback should tell us the same thing as the querying
    // the detector manually.
    ASSERT_GE(printers_found_callbacks_.size(), 1U);
    ExpectPrintersEq(printers, printers_found_callbacks_.back());
    ExpectPrintersEq(printers, detector_->GetPrinters());
  }

  // Expect that the given vectors have the same contents.  The ordering
  // may be different.
  void ExpectPrintersEq(
      const std::vector<PrinterDetector::DetectedPrinter>& expected,
      const std::vector<PrinterDetector::DetectedPrinter>& actual) {
    if (expected.size() != actual.size()) {
      ADD_FAILURE() << "Printers size mismatch, found " << actual.size()
                    << " expected " << expected.size();
      return;
    }
    std::vector<PrinterDetector::DetectedPrinter> sorted_expected = expected;
    std::vector<PrinterDetector::DetectedPrinter> sorted_actual = actual;

    std::sort(sorted_expected.begin(), sorted_expected.end(),
              [](const PrinterDetector::DetectedPrinter& a,
                 const PrinterDetector::DetectedPrinter& b) -> bool {
                return a.printer.uuid() < b.printer.uuid();
              });
    std::sort(sorted_actual.begin(), sorted_actual.end(),
              [](const PrinterDetector::DetectedPrinter& a,
                 const PrinterDetector::DetectedPrinter& b) -> bool {
                return a.printer.uuid() < b.printer.uuid();
              });
    for (size_t i = 0; i < sorted_expected.size(); ++i) {
      ExpectPrinterEq(sorted_expected[i], sorted_actual[i]);
    }
  }

  void ExpectPrinterEq(const PrinterDetector::DetectedPrinter& expected,
                       const PrinterDetector::DetectedPrinter& actual) {
    EXPECT_EQ(expected.printer.effective_uri(), actual.printer.effective_uri());
    EXPECT_EQ(expected.printer.uri(), actual.printer.uri());
    // We don't have a good way to directly check for an expected id.
    EXPECT_EQ(expected.printer.uuid(), actual.printer.uuid());
    EXPECT_EQ(expected.printer.display_name(), actual.printer.display_name());
    EXPECT_EQ(expected.printer.description(), actual.printer.description());
    EXPECT_EQ(expected.printer.IsIppEverywhere(),
              actual.printer.IsIppEverywhere());
    EXPECT_EQ(expected.printer.make_and_model(),
              actual.printer.make_and_model());
    EXPECT_EQ(expected.ppd_search_data.usb_vendor_id,
              actual.ppd_search_data.usb_vendor_id);
    EXPECT_EQ(expected.ppd_search_data.usb_product_id,
              actual.ppd_search_data.usb_product_id);
    EXPECT_EQ(expected.ppd_search_data.make_and_model,
              actual.ppd_search_data.make_and_model);
  }

  // PrinterDetector::Observer callback.
  void OnPrintersFound(
      const std::vector<PrinterDetector::DetectedPrinter>& printers) override {
    printers_found_callbacks_.push_back(printers);
  }

 protected:
  base::test::ScopedTaskEnvironment scoped_task_environment_;

  // Device listers fakes.  These are initialized when the test is constructed.
  // These pointers don't involve ownership; ownership of the listers starts
  // with this class in listers_ when the test starts, and is transferred to
  // detector_ when the detector is created.  Throughout, the listers remain
  // available to the test via these pointers.
  FakeServiceDiscoveryDeviceLister* ipp_lister_;
  FakeServiceDiscoveryDeviceLister* ipps_lister_;
  FakeServiceDiscoveryDeviceLister* ippe_lister_;
  FakeServiceDiscoveryDeviceLister* ippse_lister_;

  // Detector under test.
  std::unique_ptr<ZeroconfPrinterDetector> detector_;

  // Saved copies of all the things given to OnPrintersFound.
  std::vector<std::vector<PrinterDetector::DetectedPrinter>>
      printers_found_callbacks_;

 private:
  // Temporary storage for the device listers, between the time the test is
  // constructed and the detector is created.  Tests shouldn't access this
  // directly, use the ipp*_lister_ variables instead.
  std::map<std::string, std::unique_ptr<ServiceDiscoveryDeviceLister>> listers_;
};

// Very basic stuff, one printer of each protocol we support.
TEST_F(ZeroconfPrinterDetectorTest, SingleIppPrinter) {
  ipp_lister_->Announce("Printer1");
  CreateDetector();
  scoped_task_environment_.RunUntilIdle();
  ExpectPrintersAre({MakeExpectedPrinter("Printer1", 0)});
}

TEST_F(ZeroconfPrinterDetectorTest, SingleIppsPrinter) {
  ipps_lister_->Announce("Printer2");
  CreateDetector();
  scoped_task_environment_.RunUntilIdle();
  ExpectPrintersAre({MakeExpectedPrinter("Printer2", kFlagSSL)});
}

TEST_F(ZeroconfPrinterDetectorTest, SingleIppEverywherePrinter) {
  ippe_lister_->Announce("Printer3");
  CreateDetector();
  scoped_task_environment_.RunUntilIdle();
  ExpectPrintersAre({MakeExpectedPrinter("Printer3", kFlagIPPE)});
}

TEST_F(ZeroconfPrinterDetectorTest, SingleIppsEverywherePrinter) {
  ippse_lister_->Announce("Printer4");
  CreateDetector();
  scoped_task_environment_.RunUntilIdle();
  ExpectPrintersAre({MakeExpectedPrinter("Printer4", kFlagSSL | kFlagIPPE)});
}

// Test that an announce after the detector creation shows up as a printer.
TEST_F(ZeroconfPrinterDetectorTest, AnnounceAfterDetectorCreation) {
  CreateDetector();
  scoped_task_environment_.RunUntilIdle();
  ippse_lister_->Announce("Printer4");
  scoped_task_environment_.RunUntilIdle();
  ExpectPrintersAre({MakeExpectedPrinter("Printer4", kFlagSSL | kFlagIPPE)});
}

// Test that we use the same printer ID regardless of which service type it
// comes to us from.
TEST_F(ZeroconfPrinterDetectorTest, StableIds) {
  ipp_lister_->Announce("Printer1");
  CreateDetector();
  scoped_task_environment_.RunUntilIdle();
  ASSERT_FALSE(printers_found_callbacks_.empty());
  ASSERT_EQ(1U, printers_found_callbacks_.back().size());
  // Grab the id when it's an IPPS printer We should continue to get the same id
  // regardless of service type.
  std::string id = printers_found_callbacks_.back()[0].printer.id();

  // Remove it as an IPP printer, add it as an IPPS printer.
  ipp_lister_->Remove("Printer1");
  scoped_task_environment_.RunUntilIdle();
  ASSERT_TRUE(printers_found_callbacks_.back().empty());
  ipps_lister_->Announce("Printer1");
  scoped_task_environment_.RunUntilIdle();
  ASSERT_FALSE(printers_found_callbacks_.back().empty());
  // Id should be the same.
  ASSERT_EQ(id, printers_found_callbacks_.back()[0].printer.id());

  // Remove it as an IPPS printer, add it as an IPP-Everywhere printer.
  ipps_lister_->Remove("Printer1");
  scoped_task_environment_.RunUntilIdle();
  ASSERT_TRUE(printers_found_callbacks_.back().empty());
  ippe_lister_->Announce("Printer1");
  scoped_task_environment_.RunUntilIdle();
  ASSERT_FALSE(printers_found_callbacks_.back().empty());
  // Id should be the same.
  ASSERT_EQ(id, printers_found_callbacks_.back()[0].printer.id());

  // Remove it as an IPP-Everywhere printer, add it as an IPPS-Everywhere
  // printer.
  ippe_lister_->Remove("Printer1");
  scoped_task_environment_.RunUntilIdle();
  ASSERT_TRUE(printers_found_callbacks_.back().empty());
  ippse_lister_->Announce("Printer1");
  scoped_task_environment_.RunUntilIdle();
  ASSERT_FALSE(printers_found_callbacks_.back().empty());
  // Id should be the same.
  ASSERT_EQ(id, printers_found_callbacks_.back()[0].printer.id());
}

// Test a basic removal.
TEST_F(ZeroconfPrinterDetectorTest, Removal) {
  ipp_lister_->Announce("Printer5");
  ipp_lister_->Announce("Printer6");
  ipp_lister_->Announce("Printer7");
  ipp_lister_->Announce("Printer8");
  ipp_lister_->Announce("Printer9");
  CreateDetector();
  scoped_task_environment_.RunUntilIdle();
  ExpectPrintersAre(
      {MakeExpectedPrinter("Printer5", 0), MakeExpectedPrinter("Printer6", 0),
       MakeExpectedPrinter("Printer7", 0), MakeExpectedPrinter("Printer8", 0),
       MakeExpectedPrinter("Printer9", 0)});
  ipp_lister_->Remove("Printer7");
  scoped_task_environment_.RunUntilIdle();
  ExpectPrintersAre(
      {MakeExpectedPrinter("Printer5", 0), MakeExpectedPrinter("Printer6", 0),
       MakeExpectedPrinter("Printer8", 0), MakeExpectedPrinter("Printer9", 0)});
}

// Test that, when the same printer appears in multiple services, we
// use the highest priority one.  Priorities, from highest to lowest
// are IPPS-E, IPP-E, IPPS, IPP.
TEST_F(ZeroconfPrinterDetectorTest, ServiceTypePriorities) {
  // Advertise on all 4 services.
  ipp_lister_->Announce("Printer5");
  ipps_lister_->Announce("Printer5");
  ippe_lister_->Announce("Printer5");
  ippse_lister_->Announce("Printer5");
  CreateDetector();
  scoped_task_environment_.RunUntilIdle();
  // IPPS-E is highest priority.
  ExpectPrintersAre({MakeExpectedPrinter("Printer5", kFlagSSL | kFlagIPPE)});
  ippse_lister_->Remove("Printer5");
  scoped_task_environment_.RunUntilIdle();
  // IPP-E is highest remaining priority.
  ExpectPrintersAre({MakeExpectedPrinter("Printer5", kFlagIPPE)});

  ippe_lister_->Remove("Printer5");
  scoped_task_environment_.RunUntilIdle();
  // IPPS is highest remaining priority.
  ExpectPrintersAre({MakeExpectedPrinter("Printer5", kFlagSSL)});

  ipps_lister_->Remove("Printer5");
  scoped_task_environment_.RunUntilIdle();
  // IPP is only remaining entry.
  ExpectPrintersAre({MakeExpectedPrinter("Printer5", 0)});

  ipp_lister_->Remove("Printer5");
  scoped_task_environment_.RunUntilIdle();
  // No entries left.
  ExpectPrintersAre({});
}

// Test that cache flushes appropriately remove entries.
TEST_F(ZeroconfPrinterDetectorTest, CacheFlushes) {
  ipp_lister_->Announce("Printer6");
  ipp_lister_->Announce("Printer7");
  ipps_lister_->Announce("Printer7");
  ipps_lister_->Announce("Printer8");
  ippe_lister_->Announce("Printer8");
  ippe_lister_->Announce("Printer9");
  ippse_lister_->Announce("Printer9");
  ippse_lister_->Announce("Printer10");

  CreateDetector();
  scoped_task_environment_.RunUntilIdle();
  ExpectPrintersAre({MakeExpectedPrinter("Printer6", 0),
                     MakeExpectedPrinter("Printer7", kFlagSSL),
                     MakeExpectedPrinter("Printer8", kFlagIPPE),
                     MakeExpectedPrinter("Printer9", kFlagSSL | kFlagIPPE),
                     MakeExpectedPrinter("Printer10", kFlagSSL | kFlagIPPE)});

  ipps_lister_->Clear();

  scoped_task_environment_.RunUntilIdle();
  // With the IPPS lister cleared, Printer7 should fall back to the IPP listing.
  ExpectPrintersAre({MakeExpectedPrinter("Printer6", 0),
                     MakeExpectedPrinter("Printer7", 0),
                     MakeExpectedPrinter("Printer8", kFlagIPPE),
                     MakeExpectedPrinter("Printer9", kFlagSSL | kFlagIPPE),
                     MakeExpectedPrinter("Printer10", kFlagSSL | kFlagIPPE)});

  // We should have restarted discovery after dealing with the cache flush.
  EXPECT_TRUE(ipps_lister_->discovery_started());

  ipp_lister_->Clear();
  scoped_task_environment_.RunUntilIdle();
  // With the IPP lister cleared, Printers 6 and 7 no longer should appear.
  ExpectPrintersAre({MakeExpectedPrinter("Printer8", kFlagIPPE),
                     MakeExpectedPrinter("Printer9", kFlagSSL | kFlagIPPE),
                     MakeExpectedPrinter("Printer10", kFlagSSL | kFlagIPPE)});
  EXPECT_TRUE(ipps_lister_->discovery_started());

  ippse_lister_->Clear();
  scoped_task_environment_.RunUntilIdle();
  // With the IPPSE lister cleared, Printer10 should disappear, and Printer9
  // should fall back to the IPPE.
  ExpectPrintersAre({MakeExpectedPrinter("Printer8", kFlagIPPE),
                     MakeExpectedPrinter("Printer9", kFlagIPPE)});
  EXPECT_TRUE(ippse_lister_->discovery_started());

  // Just for kicks, announce something new at this point.
  ipps_lister_->Announce("Printer11");
  scoped_task_environment_.RunUntilIdle();
  ExpectPrintersAre({MakeExpectedPrinter("Printer8", kFlagIPPE),
                     MakeExpectedPrinter("Printer9", kFlagIPPE),
                     MakeExpectedPrinter("Printer11", kFlagSSL)});

  // Clear out the IPPE lister, leaving only the new printer we announced
  // on the IPPS lister.
  ippe_lister_->Clear();
  scoped_task_environment_.RunUntilIdle();
  // With the IPPSE lister cleared, Printer10 should disappear, and Printer9
  // should fall back to the IPPE entry.
  ExpectPrintersAre({MakeExpectedPrinter("Printer11", kFlagSSL)});
  EXPECT_TRUE(ippe_lister_->discovery_started());
}

// Test some general traffic with a mix of everything we expect to handle.
TEST_F(ZeroconfPrinterDetectorTest, GeneralMixedTraffic) {
  ipp_lister_->Announce("Printer12");
  ipps_lister_->Announce("Printer12");
  ipps_lister_->Announce("Printer13");
  ippse_lister_->Announce("Printer14");
  ipps_lister_->Announce("Printer15");

  CreateDetector();
  scoped_task_environment_.RunUntilIdle();
  ExpectPrintersAre({MakeExpectedPrinter("Printer12", kFlagSSL),
                     MakeExpectedPrinter("Printer13", kFlagSSL),
                     MakeExpectedPrinter("Printer14", kFlagSSL | kFlagIPPE),
                     MakeExpectedPrinter("Printer15", kFlagSSL)});

  ippe_lister_->Announce("Printer13");
  ipp_lister_->Announce("Printer16");
  scoped_task_environment_.RunUntilIdle();
  ExpectPrintersAre({MakeExpectedPrinter("Printer12", kFlagSSL),
                     MakeExpectedPrinter("Printer13", kFlagIPPE),
                     MakeExpectedPrinter("Printer14", kFlagSSL | kFlagIPPE),
                     MakeExpectedPrinter("Printer15", kFlagSSL),
                     MakeExpectedPrinter("Printer16", 0)});

  ipp_lister_->Remove("NonexistantPrinter");
  ipps_lister_->Remove("Printer12");
  ipps_lister_->Clear();
  ipp_lister_->Announce("Printer17");
  scoped_task_environment_.RunUntilIdle();
  ExpectPrintersAre({MakeExpectedPrinter("Printer12", 0),
                     MakeExpectedPrinter("Printer13", kFlagIPPE),
                     MakeExpectedPrinter("Printer14", kFlagSSL | kFlagIPPE),
                     MakeExpectedPrinter("Printer16", 0),
                     MakeExpectedPrinter("Printer17", 0)});
  ipp_lister_->Clear();
  ippse_lister_->Clear();
  ippe_lister_->Clear();
  scoped_task_environment_.RunUntilIdle();
  ExpectPrintersAre({});
}

}  // namespace
}  // namespace chromeos
