//
// Copyright (C) 2013 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#include "shill/wifi/wifi_provider.h"

#include <map>
#include <set>
#include <string>
#include <vector>

#include <base/format_macros.h>
#include <base/stl_util.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
#include <chromeos/dbus/service_constants.h>
#include <gtest/gtest.h>

#include "shill/mock_event_dispatcher.h"
#include "shill/mock_manager.h"
#include "shill/mock_metrics.h"
#include "shill/mock_profile.h"
#include "shill/mock_store.h"
#include "shill/net/ieee80211.h"
#include "shill/net/mock_time.h"
#include "shill/nice_mock_control.h"
#include "shill/supplicant/wpa_supplicant.h"
#include "shill/technology.h"
#include "shill/wifi/mock_wifi_service.h"
#include "shill/wifi/wifi_endpoint.h"

using base::StringPrintf;
using std::map;
using std::set;
using std::string;
using std::vector;
using ::testing::_;
using ::testing::AnyNumber;
using ::testing::ContainerEq;
using ::testing::Eq;
using ::testing::Invoke;
using ::testing::Mock;
using ::testing::NiceMock;
using ::testing::Return;
using ::testing::SetArgPointee;
using ::testing::StartsWith;
using ::testing::StrictMock;

namespace shill {

namespace {

const time_t kFirstWeek = 50;
const char kIllegalDayProfile[] = "IllegalDay";
const time_t kSecondsPerWeek = 60 * 60 * 24 * 7;
const time_t kTestDays = 20;

}  // namespace

class WiFiProviderTest : public testing::Test {
 public:
  WiFiProviderTest()
      : metrics_(nullptr),
        manager_(&control_, &dispatcher_, &metrics_),
        provider_(&control_, &dispatcher_, &metrics_, &manager_),
        default_profile_(
            new NiceMock<MockProfile>(
                &control_, &metrics_, &manager_, "default")),
        user_profile_(
            new NiceMock<MockProfile>(&control_, &metrics_, &manager_, "user")),
        storage_entry_index_(0) {
    provider_.time_ = &time_;

    string freq_string = StringPrintf("%s%d", WiFiProvider::kStorageFrequencies,
                                      0);
    profile_frequency_data_[freq_string].push_back(
        base::StringPrintf("@%" PRIu64, static_cast<uint64_t>(kFirstWeek)));
    profile_frequency_data_[freq_string].push_back("5001:1");
    profile_frequency_data_[freq_string].push_back("5002:2");

    freq_string = StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 1);
    profile_frequency_data_[freq_string].push_back(
        base::StringPrintf("@%" PRIu64, static_cast<uint64_t>(kFirstWeek) + 1));
    // Overlap one entry with previous block.
    profile_frequency_data_[freq_string].push_back("5001:1");
    profile_frequency_data_[freq_string].push_back("6001:1");
    profile_frequency_data_[freq_string].push_back("6002:2");

    freq_string = StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 2);
    profile_frequency_data_[freq_string].push_back(
        base::StringPrintf("@%" PRIu64, static_cast<uint64_t>(kFirstWeek) + 2));
    profile_frequency_data_[freq_string].push_back("7001:1");
    profile_frequency_data_[freq_string].push_back("7002:2");

    profile_frequency_data_[kIllegalDayProfile].push_back("7001:1");
    profile_frequency_data_[kIllegalDayProfile].push_back("7002:2");
  }

  virtual ~WiFiProviderTest() {}

  void SetUp() override {
    EXPECT_CALL(*default_profile_, IsDefault()).WillRepeatedly(Return(true));
    EXPECT_CALL(*default_profile_, GetStorage())
        .WillRepeatedly(Return(&default_profile_storage_));
    EXPECT_CALL(*default_profile_, GetConstStorage())
        .WillRepeatedly(Return(&default_profile_storage_));

    EXPECT_CALL(*user_profile_, IsDefault()).WillRepeatedly(Return(false));
    EXPECT_CALL(*user_profile_, GetStorage())
        .WillRepeatedly(Return(&user_profile_storage_));
    EXPECT_CALL(*user_profile_, GetConstStorage())
        .WillRepeatedly(Return(&user_profile_storage_));

    // Default expectations for UMA metrics. Individual test cases
    // will override these, by adding later expectations.
    EXPECT_CALL(metrics_, SendToUMA(
        Metrics::kMetricRememberedWiFiNetworkCount,
        _,
        Metrics::kMetricRememberedWiFiNetworkCountMin,
        Metrics::kMetricRememberedWiFiNetworkCountMax,
        Metrics::kMetricRememberedWiFiNetworkCountNumBuckets))
        .Times(AnyNumber());
    EXPECT_CALL(metrics_, SendToUMA(
        StartsWith("Network.Shill.WiFi.RememberedPrivateNetworkCount."),
        _,
        Metrics::kMetricRememberedWiFiNetworkCountMin,
        Metrics::kMetricRememberedWiFiNetworkCountMax,
        Metrics::kMetricRememberedWiFiNetworkCountNumBuckets))
        .Times(AnyNumber());
    EXPECT_CALL(metrics_, SendToUMA(
        StartsWith("Network.Shill.WiFi.RememberedSharedNetworkCount."),
        _,
        Metrics::kMetricRememberedWiFiNetworkCountMin,
        Metrics::kMetricRememberedWiFiNetworkCountMax,
        Metrics::kMetricRememberedWiFiNetworkCountNumBuckets))
        .Times(AnyNumber());
  }

  bool GetStringList(const std::string& /*group*/,
                     const std::string& key,
                     std::vector<std::string>* value) {
    if (!value) {
      return false;
    }
    if (base::ContainsKey(profile_frequency_data_, key)) {
      *value = profile_frequency_data_[key];
      return true;
    }
    return false;
  }

  bool GetIllegalDayStringList(const std::string& /*group*/,
                               const std::string& key,
                               std::vector<std::string>* value) {
    if (!value) {
      return false;
    }
    if (base::ContainsKey(profile_frequency_data_, key)) {
      *value = profile_frequency_data_[kIllegalDayProfile];
      return true;
    }
    return false;
  }

  // Used by mock invocations of RegisterService() to maintain the side-effect
  // of assigning a profile to |service|.
  void BindServiceToDefaultProfile(const ServiceRefPtr& service) {
    service->set_profile(default_profile_);
  }
  void BindServiceToUserProfile(const ServiceRefPtr& service) {
    service->set_profile(user_profile_);
  }

 protected:
  using MockWiFiServiceRefPtr = scoped_refptr<MockWiFiService>;

  void CreateServicesFromProfile(Profile* profile) {
    provider_.CreateServicesFromProfile(profile);
  }

  void LoadAndFixupServiceEntries(Profile* profile) {
    provider_.LoadAndFixupServiceEntries(profile);
  }

  void Save() {
    provider_.Save(&default_profile_storage_);
  }

  const vector<WiFiServiceRefPtr> GetServices() {
    return provider_.services_;
  }

  const WiFiProvider::EndpointServiceMap& GetServiceByEndpoint() {
    return provider_.service_by_endpoint_;
  }

  bool GetRunning() {
    return provider_.running_;
  }

  void AddStringParameterToStorage(MockStore* storage,
                                   const string& id,
                                   const string& key,
                                   const string& value) {
    EXPECT_CALL(*storage, GetString(id, key, _))
        .WillRepeatedly(DoAll(SetArgPointee<2>(value),
                              Return(true)));
  }

  // Adds service to profile's storage. But does not set profile on the Service.
  string AddServiceToProfileStorage(Profile* profile,
                                    const char* ssid,
                                    const char* mode,
                                    const char* security,
                                    bool is_hidden,
                                    bool provide_hidden) {
    string id = base::StringPrintf("entry_%d", storage_entry_index_);
    auto profile_storage = static_cast<MockStore*>(profile->GetStorage());
    EXPECT_CALL(*profile_storage, GetString(id, _, _))
        .WillRepeatedly(Return(false));
    AddStringParameterToStorage(
        profile_storage, id, WiFiService::kStorageType, kTypeWifi);
    if (ssid) {
      const string ssid_string(ssid);
      const string hex_ssid(
          base::HexEncode(ssid_string.data(), ssid_string.size()));
      AddStringParameterToStorage(
          profile_storage, id, WiFiService::kStorageSSID, hex_ssid);
    }
    if (mode) {
      AddStringParameterToStorage(
          profile_storage, id, WiFiService::kStorageMode, mode);
    }
    if (security) {
      AddStringParameterToStorage(
          profile_storage, id, WiFiService::kStorageSecurity, security);
    }
    if (provide_hidden) {
      EXPECT_CALL(*profile_storage, GetBool(id, kWifiHiddenSsid, _))
          .WillRepeatedly(
              DoAll(SetArgPointee<2>(is_hidden), Return(true)));
    } else {
      EXPECT_CALL(*profile_storage, GetBool(id, kWifiHiddenSsid, _))
          .WillRepeatedly(Return(false));
    }
    storage_entry_index_++;
    return id;
  }

  void SetServiceParameters(const char* ssid,
                            const char* mode,
                            const char* security_class,
                            bool is_hidden,
                            bool provide_hidden,
                            KeyValueStore* args) {
    args->SetString(kTypeProperty, kTypeWifi);
    if (ssid) {
      // TODO(pstew): When Chrome switches to using kWifiHexSsid primarily for
      // GetService and friends, we should switch to doing so here ourselves.
      args->SetString(kSSIDProperty, ssid);
    }
    if (mode) {
      args->SetString(kModeProperty, mode);
    }
    if (security_class) {
      args->SetString(kSecurityClassProperty, security_class);
    }
    if (provide_hidden) {
      args->SetBool(kWifiHiddenSsid, is_hidden);
    }
  }

  ServiceRefPtr CreateTemporaryService(const char* ssid,
                                       const char* mode,
                                       const char* security,
                                       bool is_hidden,
                                       bool provide_hidden,
                                       Error* error) {
    KeyValueStore args;
    SetServiceParameters(
        ssid, mode, security, is_hidden, provide_hidden, &args);
    return provider_.CreateTemporaryService(args, error);
  }

  WiFiServiceRefPtr GetService(const char* ssid,
                               const char* mode,
                               const char* security_class,
                               bool is_hidden,
                               bool provide_hidden,
                               Error* error) {
    KeyValueStore args;
    SetServiceParameters(
        ssid, mode, security_class, is_hidden, provide_hidden, &args);
    return provider_.GetWiFiService(args, error);
  }

  WiFiServiceRefPtr GetWiFiService(const KeyValueStore& args, Error* error) {
    return provider_.GetWiFiService(args, error);
  }

  WiFiServiceRefPtr FindService(const vector<uint8_t>& ssid,
                                const string& mode,
                                const string& security) {
    return provider_.FindService(ssid, mode, security);
  }
  WiFiEndpointRefPtr MakeEndpoint(const string& ssid, const string& bssid,
                                  uint16_t frequency, int16_t signal_dbm) {
    return WiFiEndpoint::MakeOpenEndpoint(
        nullptr, nullptr, ssid, bssid,
        WPASupplicant::kNetworkModeInfrastructure, frequency, signal_dbm);
  }
  MockWiFiServiceRefPtr AddMockService(const vector<uint8_t>& ssid,
                                       const string& mode,
                                       const string& security,
                                       bool hidden_ssid) {
    MockWiFiServiceRefPtr service = new MockWiFiService(
        &control_,
        &dispatcher_,
        &metrics_,
        &manager_,
        &provider_,
        ssid,
        mode,
        security,
        hidden_ssid);
    provider_.services_.push_back(service);
    return service;
  }
  void AddEndpointToService(WiFiServiceRefPtr service,
                            const WiFiEndpointConstRefPtr& endpoint) {
    provider_.service_by_endpoint_[endpoint.get()] = service;
  }

  void BuildFreqCountStrings(vector<string>* strings) {
    // NOTE: These strings match the frequencies in |BuildFreqCountMap|.  They
    // are also provided, here, in sorted order to match the frequency map
    // (iterators for which will provide them in frequency-sorted order).
    static const char* const kStrings[] = {
      "@20", "5180:14", "5240:16", "5745:7", "5765:4", "5785:14", "5805:5"
    };
    if (!strings) {
      LOG(ERROR) << "NULL |strings|.";
      return;
    }
    for (size_t i = 0; i < arraysize(kStrings); ++i) {
      (*strings).push_back(kStrings[i]);
    }
  }

  void BuildFreqCountMap(WiFiProvider::ConnectFrequencyMap* frequencies) {
    // NOTE: These structures match the strings in |BuildFreqCountStrings|.
    static const struct FreqCount {
      uint16_t freq;
      int64_t count;
    } kConnectFreq[] = {
      {5180, 14},
      {5240, 16},
      {5745, 7},
      {5765, 4},
      {5785, 14},
      {5805, 5}
    };
    if (!frequencies) {
      LOG(ERROR) << "NULL |frequencies|.";
      return;
    }
    for (size_t i = 0; i < arraysize(kConnectFreq); ++i) {
      (*frequencies)[kConnectFreq[i].freq] = kConnectFreq[i].count;
    }
  }

  void LoadConnectCountByFrequency(time_t today_seconds) {
    provider_.time_ = &time_;
    EXPECT_CALL(time_, GetSecondsSinceEpoch()).WillOnce(Return(today_seconds));
    const string kGroupId =
        StringPrintf("%s_0_0_%s_%s", kTypeWifi, kModeManaged, kSecurityNone);
    EXPECT_CALL(default_profile_storage_,
                GetString(kGroupId, _, _)).WillRepeatedly(Return(true));
    set<string> groups;
    groups.insert(kGroupId);
    EXPECT_CALL(default_profile_storage_, GetGroups()).WillOnce(Return(groups));
    // Provide data for block[0] through block[2] (block[3] is empty).
    EXPECT_CALL(
        default_profile_storage_,
        GetStringList(
            WiFiProvider::kStorageId,
            StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 0), _)).
        WillOnce(Invoke(this, &WiFiProviderTest::GetStringList));
    EXPECT_CALL(
        default_profile_storage_,
        GetStringList(
            WiFiProvider::kStorageId,
            StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 1), _)).
        WillOnce(Invoke(this, &WiFiProviderTest::GetStringList));
    EXPECT_CALL(
        default_profile_storage_,
        GetStringList(
            WiFiProvider::kStorageId,
            StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 2), _)).
        WillOnce(Invoke(this, &WiFiProviderTest::GetStringList));
    EXPECT_CALL(
        default_profile_storage_,
        GetStringList(
            WiFiProvider::kStorageId,
            StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 3), _)).
        WillOnce(Invoke(this, &WiFiProviderTest::GetStringList));

    LoadAndFixupServiceEntries(default_profile_.get());
  }

  map<string, vector<string>> profile_frequency_data_;
  NiceMockControl control_;
  MockEventDispatcher dispatcher_;
  MockMetrics metrics_;
  MockTime time_;
  StrictMock<MockManager> manager_;
  WiFiProvider provider_;
  scoped_refptr<MockProfile> default_profile_;
  scoped_refptr<MockProfile> user_profile_;
  StrictMock<MockStore> default_profile_storage_;
  StrictMock<MockStore> user_profile_storage_;
  int storage_entry_index_;  // shared across profiles
};

MATCHER(TypeWiFiPropertyMatch, "") {
  return arg.properties().size() == 1 &&
      arg.LookupString(kTypeProperty, "") == kTypeWifi;
}

MATCHER_P(RefPtrMatch, ref, "") {
  return ref.get() == arg.get();
}

TEST_F(WiFiProviderTest, Start) {
  // Doesn't do anything really.  Just testing for no crash.
  EXPECT_TRUE(GetServices().empty());
  EXPECT_FALSE(GetRunning());
  provider_.Start();
  EXPECT_TRUE(GetServices().empty());
  EXPECT_TRUE(GetRunning());
  EXPECT_TRUE(GetServiceByEndpoint().empty());
  EXPECT_FALSE(provider_.disable_vht());
}

TEST_F(WiFiProviderTest, Stop) {
  MockWiFiServiceRefPtr service0 = AddMockService(vector<uint8_t>(1, '0'),
                                                  kModeManaged,
                                                  kSecurityNone,
                                                  false);
  MockWiFiServiceRefPtr service1 = AddMockService(vector<uint8_t>(1, '1'),
                                                  kModeManaged,
                                                  kSecurityNone,
                                                  false);
  WiFiEndpointRefPtr endpoint = MakeEndpoint("", "00:00:00:00:00:00", 0, 0);
  AddEndpointToService(service0, endpoint);

  EXPECT_EQ(2, GetServices().size());
  EXPECT_FALSE(GetServiceByEndpoint().empty());
  EXPECT_CALL(*service0, ResetWiFi()).Times(1);
  EXPECT_CALL(*service1, ResetWiFi()).Times(1);
  EXPECT_CALL(manager_, DeregisterService(RefPtrMatch(service0))).Times(1);
  EXPECT_CALL(manager_, DeregisterService(RefPtrMatch(service1))).Times(1);
  provider_.Stop();
  // Verify now, so it's clear that this happened as a result of the call
  // above, and not anything in the destructor(s).
  Mock::VerifyAndClearExpectations(service0.get());
  Mock::VerifyAndClearExpectations(service1.get());
  Mock::VerifyAndClearExpectations(&manager_);
  EXPECT_TRUE(GetServices().empty());
  EXPECT_TRUE(GetServiceByEndpoint().empty());
}

TEST_F(WiFiProviderTest, CreateServicesFromProfileWithNoGroups) {
  EXPECT_CALL(default_profile_storage_,
              GetGroupsWithProperties(TypeWiFiPropertyMatch()))
      .WillOnce(Return(set<string>()));
  EXPECT_CALL(metrics_, SendToUMA(
      Metrics::kMetricRememberedWiFiNetworkCount,
      0,
      Metrics::kMetricRememberedWiFiNetworkCountMin,
      Metrics::kMetricRememberedWiFiNetworkCountMax,
      Metrics::kMetricRememberedWiFiNetworkCountNumBuckets));
  CreateServicesFromProfile(default_profile_.get());
  EXPECT_TRUE(GetServices().empty());
}

TEST_F(WiFiProviderTest, CreateServicesFromProfileMissingSSID) {
  set<string> groups;
  groups.insert(
      AddServiceToProfileStorage(
          default_profile_.get(), nullptr, kModeManaged, kSecurityNone, false,
          true));
  EXPECT_CALL(default_profile_storage_,
              GetGroupsWithProperties(TypeWiFiPropertyMatch()))
      .WillRepeatedly(Return(groups));
  EXPECT_CALL(metrics_, SendToUMA(
      Metrics::kMetricRememberedWiFiNetworkCount,
      0,
      Metrics::kMetricRememberedWiFiNetworkCountMin,
      Metrics::kMetricRememberedWiFiNetworkCountMax,
      Metrics::kMetricRememberedWiFiNetworkCountNumBuckets));
  CreateServicesFromProfile(default_profile_.get());
  EXPECT_TRUE(GetServices().empty());
}

TEST_F(WiFiProviderTest, CreateServicesFromProfileEmptySSID) {
  set<string> groups;
  groups.insert(
      AddServiceToProfileStorage(
          default_profile_.get(), "", kModeManaged, kSecurityNone, false,
          true));
  EXPECT_CALL(default_profile_storage_,
              GetGroupsWithProperties(TypeWiFiPropertyMatch()))
      .WillRepeatedly(Return(groups));
  EXPECT_CALL(metrics_, SendToUMA(
      Metrics::kMetricRememberedWiFiNetworkCount,
      0,
      Metrics::kMetricRememberedWiFiNetworkCountMin,
      Metrics::kMetricRememberedWiFiNetworkCountMax,
      Metrics::kMetricRememberedWiFiNetworkCountNumBuckets));
  CreateServicesFromProfile(default_profile_.get());
  EXPECT_TRUE(GetServices().empty());
}

TEST_F(WiFiProviderTest, CreateServicesFromProfileMissingMode) {
  set<string> groups;
  groups.insert(
      AddServiceToProfileStorage(
          default_profile_.get(), "foo", nullptr, kSecurityNone, false, true));
  EXPECT_CALL(default_profile_storage_,
              GetGroupsWithProperties(TypeWiFiPropertyMatch()))
      .WillRepeatedly(Return(groups));
  EXPECT_CALL(metrics_, SendToUMA(
      Metrics::kMetricRememberedWiFiNetworkCount,
      0,
      Metrics::kMetricRememberedWiFiNetworkCountMin,
      Metrics::kMetricRememberedWiFiNetworkCountMax,
      Metrics::kMetricRememberedWiFiNetworkCountNumBuckets));
  CreateServicesFromProfile(default_profile_.get());
  EXPECT_TRUE(GetServices().empty());
}

TEST_F(WiFiProviderTest, CreateServicesFromProfileEmptyMode) {
  set<string> groups;
  groups.insert(
      AddServiceToProfileStorage(
          default_profile_.get(), "foo", "", kSecurityNone, false, true));
  EXPECT_CALL(default_profile_storage_,
              GetGroupsWithProperties(TypeWiFiPropertyMatch()))
      .WillRepeatedly(Return(groups));
  EXPECT_CALL(metrics_, SendToUMA(
      Metrics::kMetricRememberedWiFiNetworkCount,
      0,
      Metrics::kMetricRememberedWiFiNetworkCountMin,
      Metrics::kMetricRememberedWiFiNetworkCountMax,
      Metrics::kMetricRememberedWiFiNetworkCountNumBuckets));
  CreateServicesFromProfile(default_profile_.get());
  EXPECT_TRUE(GetServices().empty());
}

TEST_F(WiFiProviderTest, CreateServicesFromProfileMissingSecurity) {
  set<string> groups;
  groups.insert(
      AddServiceToProfileStorage(
          default_profile_.get(), "foo", kModeManaged, nullptr, false, true));
  EXPECT_CALL(default_profile_storage_,
              GetGroupsWithProperties(TypeWiFiPropertyMatch()))
      .WillRepeatedly(Return(groups));
  EXPECT_CALL(metrics_, SendToUMA(
      Metrics::kMetricRememberedWiFiNetworkCount,
      0,
      Metrics::kMetricRememberedWiFiNetworkCountMin,
      Metrics::kMetricRememberedWiFiNetworkCountMax,
      Metrics::kMetricRememberedWiFiNetworkCountNumBuckets));
  CreateServicesFromProfile(default_profile_.get());
  EXPECT_TRUE(GetServices().empty());
}

TEST_F(WiFiProviderTest, CreateServicesFromProfileEmptySecurity) {
  set<string> groups;
  groups.insert(
      AddServiceToProfileStorage(
          default_profile_.get(), "foo", kModeManaged, "", false, true));
  EXPECT_CALL(default_profile_storage_,
              GetGroupsWithProperties(TypeWiFiPropertyMatch()))
      .WillRepeatedly(Return(groups));
  EXPECT_CALL(metrics_, SendToUMA(
      Metrics::kMetricRememberedWiFiNetworkCount,
      0,
      Metrics::kMetricRememberedWiFiNetworkCountMin,
      Metrics::kMetricRememberedWiFiNetworkCountMax,
      Metrics::kMetricRememberedWiFiNetworkCountNumBuckets));
  CreateServicesFromProfile(default_profile_.get());
  EXPECT_TRUE(GetServices().empty());
}

TEST_F(WiFiProviderTest, CreateServicesFromProfileMissingHidden) {
  set<string> groups;
  groups.insert(
      AddServiceToProfileStorage(
          default_profile_.get(), "foo", kModeManaged, kSecurityNone, false,
          false));
  EXPECT_CALL(default_profile_storage_,
              GetGroupsWithProperties(TypeWiFiPropertyMatch()))
      .WillRepeatedly(Return(groups));
  EXPECT_CALL(metrics_, SendToUMA(
      Metrics::kMetricRememberedWiFiNetworkCount,
      0,
      Metrics::kMetricRememberedWiFiNetworkCountMin,
      Metrics::kMetricRememberedWiFiNetworkCountMax,
      Metrics::kMetricRememberedWiFiNetworkCountNumBuckets));
  CreateServicesFromProfile(default_profile_.get());
  EXPECT_TRUE(GetServices().empty());
}

TEST_F(WiFiProviderTest, CreateServicesFromProfileSingle) {
  set<string> groups;
  string kSSID("foo");
  groups.insert(
      AddServiceToProfileStorage(
          default_profile_.get(),
          kSSID.c_str(), kModeManaged, kSecurityNone, false, true));
  EXPECT_CALL(default_profile_storage_,
              GetGroupsWithProperties(TypeWiFiPropertyMatch()))
      .WillRepeatedly(Return(groups));
  EXPECT_CALL(manager_, RegisterService(_))
      .WillOnce(Invoke(this, &WiFiProviderTest::BindServiceToDefaultProfile));
  EXPECT_CALL(manager_, IsServiceEphemeral(_)).WillRepeatedly(Return(false));
  EXPECT_CALL(metrics_, SendToUMA(
      Metrics::kMetricRememberedWiFiNetworkCount,
      1,
      Metrics::kMetricRememberedWiFiNetworkCountMin,
      Metrics::kMetricRememberedWiFiNetworkCountMax,
      Metrics::kMetricRememberedWiFiNetworkCountNumBuckets)).Times(2);
  CreateServicesFromProfile(default_profile_.get());
  Mock::VerifyAndClearExpectations(&manager_);
  EXPECT_EQ(1, GetServices().size());

  const WiFiServiceRefPtr service = GetServices().front();
  const string service_ssid(service->ssid().begin(), service->ssid().end());
  EXPECT_EQ(kSSID, service_ssid);
  EXPECT_EQ(kModeManaged, service->mode());
  EXPECT_TRUE(service->IsSecurityMatch(kSecurityNone));

  EXPECT_CALL(manager_, RegisterService(_)).Times(0);
  EXPECT_CALL(manager_, IsServiceEphemeral(_)).WillRepeatedly(Return(false));
  CreateServicesFromProfile(default_profile_.get());
  EXPECT_EQ(1, GetServices().size());
}

TEST_F(WiFiProviderTest, CreateServicesFromProfileHiddenButConnected) {
  set<string> groups;
  string kSSID("foo");
  groups.insert(
      AddServiceToProfileStorage(
          default_profile_.get(),
          kSSID.c_str(), kModeManaged, kSecurityNone, true, true));
  EXPECT_CALL(default_profile_storage_,
              GetGroupsWithProperties(TypeWiFiPropertyMatch()))
      .WillRepeatedly(Return(groups));
  EXPECT_CALL(manager_, RegisterService(_))
      .WillOnce(Invoke(this, &WiFiProviderTest::BindServiceToDefaultProfile));
  EXPECT_CALL(manager_, IsServiceEphemeral(_)).WillRepeatedly(Return(false));
  EXPECT_CALL(manager_, IsTechnologyConnected(Technology::kWifi))
      .WillOnce(Return(true));
  EXPECT_CALL(manager_, RequestScan(_, _)).Times(0);
  EXPECT_CALL(metrics_, SendToUMA(
      Metrics::kMetricRememberedWiFiNetworkCount,
      1,
      Metrics::kMetricRememberedWiFiNetworkCountMin,
      Metrics::kMetricRememberedWiFiNetworkCountMax,
      Metrics::kMetricRememberedWiFiNetworkCountNumBuckets)).Times(2);
  CreateServicesFromProfile(default_profile_.get());
  Mock::VerifyAndClearExpectations(&manager_);

  EXPECT_CALL(manager_, RegisterService(_)).Times(0);
  EXPECT_CALL(manager_, IsTechnologyConnected(_)).Times(0);
  EXPECT_CALL(manager_, IsServiceEphemeral(_)).WillRepeatedly(Return(false));
  CreateServicesFromProfile(default_profile_.get());
}

TEST_F(WiFiProviderTest, CreateServicesFromProfileHiddenNotConnected) {
  set<string> groups;
  string kSSID("foo");
  groups.insert(AddServiceToProfileStorage(default_profile_.get(),
      kSSID.c_str(), kModeManaged, kSecurityNone, true, true));
  EXPECT_CALL(default_profile_storage_,
              GetGroupsWithProperties(TypeWiFiPropertyMatch()))
      .WillRepeatedly(Return(groups));
  EXPECT_CALL(manager_, RegisterService(_))
      .WillOnce(Invoke(this, &WiFiProviderTest::BindServiceToDefaultProfile));
  EXPECT_CALL(manager_, IsServiceEphemeral(_)).WillRepeatedly(Return(false));
  EXPECT_CALL(manager_, IsTechnologyConnected(Technology::kWifi))
      .WillOnce(Return(false));
  EXPECT_CALL(manager_, RequestScan(kTypeWifi, _)).Times(1);
  EXPECT_CALL(metrics_, SendToUMA(
      Metrics::kMetricRememberedWiFiNetworkCount,
      1,
      Metrics::kMetricRememberedWiFiNetworkCountMin,
      Metrics::kMetricRememberedWiFiNetworkCountMax,
      Metrics::kMetricRememberedWiFiNetworkCountNumBuckets)).Times(2);
  CreateServicesFromProfile(default_profile_.get());
  Mock::VerifyAndClearExpectations(&manager_);

  EXPECT_CALL(manager_, RegisterService(_)).Times(0);
  EXPECT_CALL(manager_, IsTechnologyConnected(_)).Times(0);
  EXPECT_CALL(manager_, RequestScan(_, _)).Times(0);
  EXPECT_CALL(manager_, IsServiceEphemeral(_)).WillRepeatedly(Return(false));
  CreateServicesFromProfile(default_profile_.get());
}

TEST_F(WiFiProviderTest, CreateTemporaryServiceFromProfileNonWiFi) {
  const string kEntryName("name");
  auto profile_storage =
      static_cast<MockStore*>(default_profile_->GetStorage());
  EXPECT_CALL(*profile_storage,
              GetString(kEntryName, WiFiService::kStorageType, _))
      .WillOnce(Return(false));
  Error error;
  EXPECT_EQ(nullptr,
            provider_.CreateTemporaryServiceFromProfile(
                default_profile_, kEntryName, &error));
  EXPECT_FALSE(error.IsSuccess());
  EXPECT_THAT(error.message(),
              StartsWith("Unspecified or invalid network type"));
}

TEST_F(WiFiProviderTest, CreateTemporaryServiceFromProfileMissingSSID) {
  string entry_name = AddServiceToProfileStorage(
          default_profile_.get(), nullptr, kModeManaged, kSecurityNone, false,
          true);
  Error error;
  EXPECT_EQ(nullptr,
            provider_.CreateTemporaryServiceFromProfile(
                default_profile_, entry_name, &error));
  EXPECT_FALSE(error.IsSuccess());
  EXPECT_THAT(error.message(), StartsWith("Unspecified or invalid SSID"));
}

TEST_F(WiFiProviderTest, CreateTemporaryServiceFromProfileMissingMode) {
  string entry_name = AddServiceToProfileStorage(
      default_profile_.get(), "foo", "", kSecurityNone, false, true);

  Error error;
  EXPECT_EQ(nullptr,
            provider_.CreateTemporaryServiceFromProfile(
                default_profile_, entry_name, &error));
  EXPECT_FALSE(error.IsSuccess());
  EXPECT_THAT(error.message(), StartsWith("Network mode not specified"));
}

TEST_F(WiFiProviderTest, CreateTemporaryServiceFromProfileMissingSecurity) {
  string entry_name = AddServiceToProfileStorage(
      default_profile_.get(), "foo", kModeManaged, "", false, true);

  Error error;
  EXPECT_EQ(nullptr,
            provider_.CreateTemporaryServiceFromProfile(
                default_profile_, entry_name, &error));
  EXPECT_FALSE(error.IsSuccess());
  EXPECT_THAT(error.message(),
              StartsWith("Unspecified or invalid security mode"));
}

TEST_F(WiFiProviderTest, CreateTemporaryServiceFromProfileMissingHidden) {
  string entry_name = AddServiceToProfileStorage(
      default_profile_.get(), "foo", kModeManaged, kSecurityNone, false, false);

  Error error;
  EXPECT_EQ(nullptr,
            provider_.CreateTemporaryServiceFromProfile(
                default_profile_, entry_name, &error));
  EXPECT_FALSE(error.IsSuccess());
  EXPECT_THAT(error.message(),
              StartsWith("Hidden SSID not specified"));
}

TEST_F(WiFiProviderTest, CreateTemporaryServiceFromProfile) {
  string entry_name = AddServiceToProfileStorage(
      default_profile_.get(), "foo", kModeManaged, kSecurityNone, false, true);

  Error error;
  EXPECT_NE(nullptr,
            provider_.CreateTemporaryServiceFromProfile(
                default_profile_, entry_name, &error));
  EXPECT_TRUE(error.IsSuccess());
}

TEST_F(WiFiProviderTest, CreateTwoServices) {
  set<string> groups;
  groups.insert(
      AddServiceToProfileStorage(
          default_profile_.get(), "foo", kModeManaged, kSecurityNone, false,
          true));
  groups.insert(
      AddServiceToProfileStorage(
          default_profile_.get(), "bar", kModeManaged, kSecurityNone, true,
          true));
  EXPECT_CALL(default_profile_storage_,
              GetGroupsWithProperties(TypeWiFiPropertyMatch()))
      .WillRepeatedly(Return(groups));
  EXPECT_CALL(manager_, RegisterService(_))
      .Times(2)
      .WillRepeatedly(
          Invoke(this, &WiFiProviderTest::BindServiceToDefaultProfile));
  EXPECT_CALL(manager_, IsServiceEphemeral(_)).WillRepeatedly(Return(false));
  EXPECT_CALL(manager_, IsTechnologyConnected(Technology::kWifi))
      .WillOnce(Return(true));
  EXPECT_CALL(manager_, RequestScan(kTypeWifi, _)).Times(0);
  EXPECT_CALL(metrics_, SendToUMA(
      Metrics::kMetricRememberedWiFiNetworkCount,
      2,
      Metrics::kMetricRememberedWiFiNetworkCountMin,
      Metrics::kMetricRememberedWiFiNetworkCountMax,
      Metrics::kMetricRememberedWiFiNetworkCountNumBuckets));
  CreateServicesFromProfile(default_profile_.get());
  Mock::VerifyAndClearExpectations(&manager_);

  EXPECT_EQ(2, GetServices().size());
}

TEST_F(WiFiProviderTest, ServiceSourceStats) {
  set<string> default_profile_groups;
  default_profile_groups.insert(
      AddServiceToProfileStorage(
          default_profile_.get(), "foo", kModeManaged, kSecurityWpa, false,
          true));
  EXPECT_CALL(default_profile_storage_,
              GetGroupsWithProperties(TypeWiFiPropertyMatch()))
      .WillRepeatedly(Return(default_profile_groups));
  EXPECT_CALL(manager_, RegisterService(_))
      .WillOnce(Invoke(this, &WiFiProviderTest::BindServiceToDefaultProfile));
  EXPECT_CALL(manager_, IsServiceEphemeral(_)).WillRepeatedly(Return(false));
  // Processing default profile does not generate UMA metrics.
  EXPECT_CALL(metrics_, SendToUMA(
      StartsWith("Network.Shill.WiFi.RememberedSystemNetworkCount."),
      _, _, _, _))
      .Times(0);
  EXPECT_CALL(metrics_, SendToUMA(
      StartsWith("Network.Shill.WiFi.RememberedUserNetworkCount."),
      _, _, _, _))
      .Times(0);
  CreateServicesFromProfile(default_profile_.get());
  Mock::VerifyAndClearExpectations(&manager_);

  set<string> user_profile_groups;
  user_profile_groups.insert(
      AddServiceToProfileStorage(
          user_profile_.get(), "bar", kModeManaged, kSecurityRsn, false, true));
  EXPECT_CALL(user_profile_storage_,
              GetGroupsWithProperties(TypeWiFiPropertyMatch()))
      .WillRepeatedly(Return(user_profile_groups));
  EXPECT_CALL(manager_, RegisterService(_))
      .WillOnce(Invoke(this, &WiFiProviderTest::BindServiceToUserProfile));
  EXPECT_CALL(manager_, IsServiceEphemeral(_)).WillRepeatedly(Return(false));
  // Processing user profile generates metrics for both, default profile,
  // and user profile.
  EXPECT_CALL(metrics_, SendToUMA(
      StartsWith("Network.Shill.WiFi.RememberedSystemNetworkCount."),
      0,
      Metrics::kMetricRememberedWiFiNetworkCountMin,
      Metrics::kMetricRememberedWiFiNetworkCountMax,
      Metrics::kMetricRememberedWiFiNetworkCountNumBuckets))
      .Times(3);  // none, wep, 802.1x
  EXPECT_CALL(metrics_, SendToUMA(
      StartsWith("Network.Shill.WiFi.RememberedUserNetworkCount."),
      0,
      Metrics::kMetricRememberedWiFiNetworkCountMin,
      Metrics::kMetricRememberedWiFiNetworkCountMax,
      Metrics::kMetricRememberedWiFiNetworkCountNumBuckets))
      .Times(3);  // none, wep, 802.1x
  EXPECT_CALL(metrics_, SendToUMA(
      StartsWith("Network.Shill.WiFi.RememberedSystemNetworkCount.psk"),
      1,
      Metrics::kMetricRememberedWiFiNetworkCountMin,
      Metrics::kMetricRememberedWiFiNetworkCountMax,
      Metrics::kMetricRememberedWiFiNetworkCountNumBuckets));
  EXPECT_CALL(metrics_, SendToUMA(
      StartsWith("Network.Shill.WiFi.RememberedUserNetworkCount.psk"),
      1,
      Metrics::kMetricRememberedWiFiNetworkCountMin,
      Metrics::kMetricRememberedWiFiNetworkCountMax,
      Metrics::kMetricRememberedWiFiNetworkCountNumBuckets));
  CreateServicesFromProfile(user_profile_.get());
}

TEST_F(WiFiProviderTest, GetServiceEmptyMode) {
  Error error;
  EXPECT_FALSE(GetService("foo", "", kSecurityNone,
                          false, false, &error).get());
  EXPECT_EQ(Error::kNotSupported, error.type());
}

TEST_F(WiFiProviderTest, GetServiceNoMode) {
  Error error;
  EXPECT_CALL(manager_, RegisterService(_)).Times(1);
  EXPECT_TRUE(GetService("foo", nullptr, kSecurityNone,
                          false, false, &error).get());
  EXPECT_TRUE(error.IsSuccess());
}

TEST_F(WiFiProviderTest, GetServiceBadMode) {
  Error error;
  EXPECT_FALSE(GetService("foo", "BogoMesh",
                          kSecurityNone,
                          false, false, &error).get());
  EXPECT_EQ(Error::kNotSupported, error.type());
  EXPECT_EQ("service mode is unsupported", error.message());
}

TEST_F(WiFiProviderTest, GetServiceNoSSID) {
  Error error;
  EXPECT_FALSE(GetService(nullptr, kModeManaged,
                          kSecurityNone, false, false,
                          &error).get());
  EXPECT_EQ(Error::kInvalidArguments, error.type());
  EXPECT_EQ("must specify SSID", error.message());
}

TEST_F(WiFiProviderTest, GetServiceEmptySSID) {
  Error error;
  EXPECT_FALSE(GetService("", kModeManaged,
                          kSecurityNone, false, false,
                          &error).get());
  EXPECT_EQ(Error::kInvalidNetworkName, error.type());
  EXPECT_EQ("SSID is too short", error.message());
}

TEST_F(WiFiProviderTest, GetServiceLongSSID) {
  Error error;
  string ssid(IEEE_80211::kMaxSSIDLen + 1, '0');
  EXPECT_FALSE(GetService(ssid.c_str(), kModeManaged,
                          kSecurityNone, false, false,
                          &error).get());
  EXPECT_EQ(Error::kInvalidNetworkName, error.type());
  EXPECT_EQ("SSID is too long", error.message());
}

TEST_F(WiFiProviderTest, GetServiceJustLongEnoughSSID) {
  Error error;
  string ssid(IEEE_80211::kMaxSSIDLen, '0');
  EXPECT_CALL(manager_, RegisterService(_)).Times(1);
  EXPECT_TRUE(GetService(ssid.c_str(), kModeManaged,
                         kSecurityNone, false, false,
                         &error).get());
  EXPECT_TRUE(error.IsSuccess());
}

TEST_F(WiFiProviderTest, GetServiceBadSecurityClass) {
  Error error;
  EXPECT_FALSE(GetService("foo", kModeManaged,
                          kSecurityRsn, false, false,
                          &error).get());
  EXPECT_EQ(Error::kNotSupported, error.type());
  EXPECT_EQ("security class is unsupported", error.message());
}

TEST_F(WiFiProviderTest, GetServiceMinimal) {
  Error error;
  const string kSSID("foo");
  EXPECT_CALL(manager_, RegisterService(_)).Times(1);
  WiFiServiceRefPtr service = GetService(kSSID.c_str(), kModeManaged,
                                         nullptr, false, false, &error);
  EXPECT_TRUE(service.get());
  EXPECT_TRUE(error.IsSuccess());
  const string service_ssid(service->ssid().begin(), service->ssid().end());
  EXPECT_EQ(kSSID, service_ssid);
  EXPECT_EQ(kModeManaged, service->mode());

  // These two should be set to their default values if not specified.
  EXPECT_TRUE(service->IsSecurityMatch(kSecurityNone));
  EXPECT_TRUE(service->hidden_ssid());
}

TEST_F(WiFiProviderTest, GetServiceFullySpecified) {
  EXPECT_CALL(manager_, RegisterService(_)).Times(1);
  const string kSSID("bar");
  Error error;
  WiFiServiceRefPtr service0 = GetService(
      kSSID.c_str(), kModeManaged, kSecurityPsk, false, true, &error);
  Mock::VerifyAndClearExpectations(&manager_);
  EXPECT_TRUE(error.IsSuccess());
  const string service_ssid(service0->ssid().begin(), service0->ssid().end());
  EXPECT_EQ(kSSID, service_ssid);
  EXPECT_EQ(kModeManaged, service0->mode());
  EXPECT_TRUE(service0->IsSecurityMatch(kSecurityPsk));
  EXPECT_FALSE(service0->hidden_ssid());

  // Getting the same service parameters (even with a different hidden
  // parameter) should return the same service.
  EXPECT_CALL(manager_, RegisterService(_)).Times(0);
  WiFiServiceRefPtr service1 =
      GetService(kSSID.c_str(), kModeManaged, kSecurityPsk, true, true, &error);
  Mock::VerifyAndClearExpectations(&manager_);
  EXPECT_EQ(service0.get(), service1.get());
  EXPECT_EQ(1, GetServices().size());

  // Getting the same ssid with different other parameters should return
  // a different service.
  EXPECT_CALL(manager_, RegisterService(_)).Times(1);
  WiFiServiceRefPtr service2 = GetService(
      kSSID.c_str(), kModeManaged, kSecurityNone, true, true, &error);
  Mock::VerifyAndClearExpectations(&manager_);
  EXPECT_NE(service0.get(), service2.get());
  EXPECT_EQ(2, GetServices().size());
}

TEST_F(WiFiProviderTest, GetServiceByHexSsid) {
  EXPECT_CALL(manager_, RegisterService(_)).Times(1);
  const string kSSID("bar");
  const string kHexSsid(base::HexEncode(kSSID.c_str(), kSSID.length()));

  KeyValueStore args;
  args.SetString(kTypeProperty, kTypeWifi);
  args.SetString(kWifiHexSsid, kHexSsid);
  args.SetString(kSecurityProperty, kSecurityPsk);
  args.SetBool(kWifiHiddenSsid, false);

  Error error;
  WiFiServiceRefPtr service = GetWiFiService(args, &error);
  Mock::VerifyAndClearExpectations(&manager_);
  EXPECT_TRUE(error.IsSuccess());
  const string service_ssid(service->ssid().begin(), service->ssid().end());
  EXPECT_EQ(kSSID, service_ssid);
  EXPECT_EQ(kModeManaged, service->mode());
  EXPECT_TRUE(service->IsSecurityMatch(kSecurityPsk));
  EXPECT_FALSE(service->hidden_ssid());


  // While here, make sure FindSimilarService also supports kWifiHexSsid.
  Error find_error;
  ServiceRefPtr find_service = provider_.FindSimilarService(args, &find_error);
  EXPECT_TRUE(find_error.IsSuccess());
  EXPECT_EQ(service.get(), find_service.get());
}

TEST_F(WiFiProviderTest, GetServiceWithSecurityAndSecurityClassMismatched) {
  const string kSSID("bar");
  KeyValueStore args;
  args.SetString(kTypeProperty, kTypeWifi);
  args.SetString(kSSIDProperty, kSSID);
  args.SetString(kSecurityProperty, kSecurityRsn);
  args.SetString(kSecurityClassProperty, kSecurityPsk);
  args.SetBool(kWifiHiddenSsid, false);

  Error error;
  WiFiServiceRefPtr service;
  EXPECT_CALL(manager_, RegisterService(_)).Times(0);
  service = GetWiFiService(args, &error);
  EXPECT_FALSE(error.IsSuccess());
}

TEST_F(WiFiProviderTest, GetServiceWithSecurityAndSecurityClassMatching) {
  const string kSSID("bar");
  KeyValueStore args;
  args.SetString(kTypeProperty, kTypeWifi);
  args.SetString(kSSIDProperty, kSSID);
  args.SetString(kSecurityProperty, kSecurityPsk);
  args.SetString(kSecurityClassProperty, kSecurityPsk);
  args.SetBool(kWifiHiddenSsid, false);

  Error error;
  WiFiServiceRefPtr service;
  EXPECT_CALL(manager_, RegisterService(_));
  service = GetWiFiService(args, &error);
  EXPECT_TRUE(error.IsSuccess());
}

TEST_F(WiFiProviderTest,
       GetServiceWithSecurityAndSecurityClassMatchingButInvalidClass) {
  const string kSSID("bar");
  KeyValueStore args;
  args.SetString(kTypeProperty, kTypeWifi);
  args.SetString(kSSIDProperty, kSSID);
  args.SetString(kSecurityProperty, kSecurityRsn);
  args.SetString(kSecurityClassProperty, kSecurityRsn);
  args.SetBool(kWifiHiddenSsid, false);
  EXPECT_CALL(manager_, RegisterService(_)).Times(0);

  Error error;
  WiFiServiceRefPtr service = GetWiFiService(args, &error);
  Mock::VerifyAndClearExpectations(&manager_);
  EXPECT_FALSE(error.IsSuccess());
}

TEST_F(WiFiProviderTest, GetServiceBadSecurity) {
  const string kSSID("bar");
  KeyValueStore args;
  args.SetString(kTypeProperty, kTypeWifi);
  args.SetString(kSSIDProperty, kSSID);
  args.SetString(kSecurityProperty, "pig-80211");
  args.SetBool(kWifiHiddenSsid, false);

  Error error;
  WiFiServiceRefPtr service;
  EXPECT_CALL(manager_, RegisterService(_)).Times(0);
  service = GetWiFiService(args, &error);
  EXPECT_FALSE(error.IsSuccess());
  EXPECT_EQ(Error::kNotSupported, error.type());
  EXPECT_EQ("security mode is unsupported", error.message());
}

TEST_F(WiFiProviderTest, FindSimilarService) {
  // Since CreateTemporyService uses exactly the same validation as
  // GetService, don't bother with testing invalid parameters.
  const string kSSID("foo");
  KeyValueStore args;
  SetServiceParameters(
      kSSID.c_str(), kModeManaged, kSecurityNone,
      true, true, &args);
  EXPECT_CALL(manager_, RegisterService(_)).Times(1);
  Error get_service_error;
  WiFiServiceRefPtr service = GetWiFiService(args, &get_service_error);
  EXPECT_EQ(1, GetServices().size());

  {
    Error error;
    ServiceRefPtr find_service = provider_.FindSimilarService(args, &error);
    EXPECT_EQ(service.get(), find_service.get());
    EXPECT_TRUE(error.IsSuccess());
  }

  args.SetBool(kWifiHiddenSsid, false);

  {
    Error error;
    ServiceRefPtr find_service = provider_.FindSimilarService(args, &error);
    EXPECT_EQ(service.get(), find_service.get());
    EXPECT_TRUE(error.IsSuccess());
  }

  args.SetString(kSecurityClassProperty, kSecurityPsk);

  {
    Error error;
    ServiceRefPtr find_service = provider_.FindSimilarService(args, &error);
    EXPECT_EQ(nullptr, find_service.get());
    EXPECT_EQ(Error::kNotFound, error.type());
  }
}

TEST_F(WiFiProviderTest, CreateTemporaryService) {
  // Since CreateTemporyService uses exactly the same validation as
  // GetService, don't bother with testing invalid parameters.
  const string kSSID("foo");
  EXPECT_CALL(manager_, RegisterService(_)).Times(1);
  Error error;
  WiFiServiceRefPtr service0 = GetService(
      kSSID.c_str(), kModeManaged, kSecurityNone, true, true, &error);
  EXPECT_EQ(1, GetServices().size());
  Mock::VerifyAndClearExpectations(&manager_);

  EXPECT_CALL(manager_, RegisterService(_)).Times(0);
  ServiceRefPtr service1 =
      CreateTemporaryService(kSSID.c_str(), kModeManaged,
                             kSecurityNone, true, true, &error);

  // Test that a new service was created, but not registered with the
  // manager or added to the provider's service list.
  EXPECT_EQ(1, GetServices().size());
  EXPECT_TRUE(service0 != service1);
  EXPECT_TRUE(service1->HasOneRef());
}

TEST_F(WiFiProviderTest, FindServiceWPA) {
  const string kSSID("an_ssid");
  Error error;
  EXPECT_CALL(manager_, RegisterService(_)).Times(1);
  KeyValueStore args;
  SetServiceParameters(
      kSSID.c_str(), kModeManaged, nullptr, false, false, &args);
  args.SetString(kSecurityProperty, kSecurityRsn);
  WiFiServiceRefPtr service = GetWiFiService(args, &error);
  ASSERT_TRUE(service.get());
  const vector<uint8_t> ssid_bytes(kSSID.begin(), kSSID.end());
  WiFiServiceRefPtr wpa_service(FindService(ssid_bytes, kModeManaged,
                                            kSecurityWpa));
  EXPECT_TRUE(wpa_service.get());
  EXPECT_EQ(service.get(), wpa_service.get());
  WiFiServiceRefPtr rsn_service(FindService(ssid_bytes, kModeManaged,
                                            kSecurityRsn));
  EXPECT_TRUE(rsn_service.get());
  EXPECT_EQ(service.get(), rsn_service.get());
  WiFiServiceRefPtr psk_service(FindService(ssid_bytes, kModeManaged,
                                            kSecurityPsk));
  EXPECT_EQ(service.get(), psk_service.get());
  WiFiServiceRefPtr wep_service(FindService(ssid_bytes, kModeManaged,
                                            kSecurityWep));
  EXPECT_TRUE(service.get() != wep_service.get());
  EXPECT_EQ(nullptr, wep_service.get());
}

TEST_F(WiFiProviderTest, FindServiceForEndpoint) {
  EXPECT_CALL(manager_, RegisterService(_)).Times(1);
  Error error;
  const string kSSID("an_ssid");
  WiFiServiceRefPtr service = GetService(
      kSSID.c_str(), kModeManaged, kSecurityNone, false, true, &error);
  ASSERT_TRUE(service.get());
  WiFiEndpointRefPtr endpoint = MakeEndpoint(kSSID, "00:00:00:00:00:00", 0, 0);
  WiFiServiceRefPtr endpoint_service =
      provider_.FindServiceForEndpoint(endpoint);
  // Just because a matching service exists, we shouldn't necessarily have
  // it returned.  We will test that this function returns the correct
  // service if the endpoint is added below.
  EXPECT_EQ(nullptr, endpoint_service.get());
}

TEST_F(WiFiProviderTest, OnEndpointAdded) {
  provider_.Start();
  const string ssid0("an_ssid");
  const vector<uint8_t> ssid0_bytes(ssid0.begin(), ssid0.end());
  EXPECT_FALSE(FindService(ssid0_bytes, kModeManaged,
                           kSecurityNone));
  WiFiEndpointRefPtr endpoint0 = MakeEndpoint(ssid0, "00:00:00:00:00:00", 0, 0);
  EXPECT_CALL(manager_, RegisterService(_)).Times(1);
  EXPECT_CALL(manager_, UpdateService(_)).Times(1);
  provider_.OnEndpointAdded(endpoint0);
  Mock::VerifyAndClearExpectations(&manager_);
  EXPECT_EQ(1, GetServices().size());
  WiFiServiceRefPtr service0(FindService(ssid0_bytes, kModeManaged,
                                         kSecurityNone));
  EXPECT_TRUE(service0.get());
  EXPECT_TRUE(service0->HasEndpoints());
  EXPECT_EQ(1, GetServiceByEndpoint().size());
  WiFiServiceRefPtr endpoint_service =
      provider_.FindServiceForEndpoint(endpoint0);
  EXPECT_EQ(service0.get(), endpoint_service.get());

  WiFiEndpointRefPtr endpoint1 = MakeEndpoint(ssid0, "00:00:00:00:00:01", 0, 0);
  EXPECT_CALL(manager_, RegisterService(_)).Times(0);
  EXPECT_CALL(manager_, UpdateService(RefPtrMatch(service0))).Times(1);
  provider_.OnEndpointAdded(endpoint1);
  Mock::VerifyAndClearExpectations(&manager_);
  EXPECT_EQ(1, GetServices().size());

  const string ssid1("another_ssid");
  const vector<uint8_t> ssid1_bytes(ssid1.begin(), ssid1.end());
  EXPECT_FALSE(FindService(ssid1_bytes, kModeManaged,
                           kSecurityNone));
  WiFiEndpointRefPtr endpoint2 = MakeEndpoint(ssid1, "00:00:00:00:00:02",
                                              0, 0);
  EXPECT_CALL(manager_, RegisterService(_)).Times(1);
  EXPECT_CALL(manager_, UpdateService(_)).Times(1);
  provider_.OnEndpointAdded(endpoint2);
  Mock::VerifyAndClearExpectations(&manager_);
  EXPECT_EQ(2, GetServices().size());

  WiFiServiceRefPtr service1(FindService(ssid1_bytes, kModeManaged,
                                         kSecurityNone));
  EXPECT_TRUE(service1.get());
  EXPECT_TRUE(service1->HasEndpoints());
  EXPECT_TRUE(service1 != service0);
}

TEST_F(WiFiProviderTest, OnEndpointAddedWithSecurity) {
  provider_.Start();
  const string ssid0("an_ssid");
  const vector<uint8_t> ssid0_bytes(ssid0.begin(), ssid0.end());
  EXPECT_FALSE(FindService(ssid0_bytes, kModeManaged,
                           kSecurityNone));
  WiFiEndpointRefPtr endpoint0 = MakeEndpoint(ssid0, "00:00:00:00:00:00", 0, 0);
  endpoint0->set_security_mode(kSecurityRsn);
  EXPECT_CALL(manager_, RegisterService(_)).Times(1);
  EXPECT_CALL(manager_, UpdateService(_)).Times(1);
  provider_.OnEndpointAdded(endpoint0);
  Mock::VerifyAndClearExpectations(&manager_);
  EXPECT_EQ(1, GetServices().size());
  WiFiServiceRefPtr service0(FindService(ssid0_bytes, kModeManaged,
                                         kSecurityWpa));
  EXPECT_TRUE(service0.get());
  EXPECT_TRUE(service0->HasEndpoints());
  EXPECT_EQ(kSecurityPsk, service0->security_);

  WiFiEndpointRefPtr endpoint1 = MakeEndpoint(ssid0, "00:00:00:00:00:01", 0, 0);
  endpoint1->set_security_mode(kSecurityWpa);
  EXPECT_CALL(manager_, RegisterService(_)).Times(0);
  EXPECT_CALL(manager_, UpdateService(RefPtrMatch(service0))).Times(1);
  provider_.OnEndpointAdded(endpoint1);
  Mock::VerifyAndClearExpectations(&manager_);
  EXPECT_EQ(1, GetServices().size());

  const string ssid1("another_ssid");
  const vector<uint8_t> ssid1_bytes(ssid1.begin(), ssid1.end());
  EXPECT_FALSE(FindService(ssid1_bytes, kModeManaged,
                           kSecurityNone));
  WiFiEndpointRefPtr endpoint2 = MakeEndpoint(ssid1, "00:00:00:00:00:02", 0, 0);
  endpoint2->set_security_mode(kSecurityWpa);
  EXPECT_CALL(manager_, RegisterService(_)).Times(1);
  EXPECT_CALL(manager_, UpdateService(_)).Times(1);
  provider_.OnEndpointAdded(endpoint2);
  Mock::VerifyAndClearExpectations(&manager_);
  EXPECT_EQ(2, GetServices().size());

  WiFiServiceRefPtr service1(FindService(ssid1_bytes, kModeManaged,
                                         kSecurityRsn));
  EXPECT_TRUE(service1.get());
  EXPECT_TRUE(service1->HasEndpoints());
  EXPECT_EQ(kSecurityPsk, service1->security_);
  EXPECT_TRUE(service1 != service0);
}

TEST_F(WiFiProviderTest, OnEndpointAddedWhileStopped) {
  // If we don't call provider_.Start(), OnEndpointAdded should have no effect.
  const string ssid("an_ssid");
  WiFiEndpointRefPtr endpoint = MakeEndpoint(ssid, "00:00:00:00:00:00", 0, 0);
  EXPECT_CALL(manager_, RegisterService(_)).Times(0);
  EXPECT_CALL(manager_, UpdateService(_)).Times(0);
  provider_.OnEndpointAdded(endpoint);
  EXPECT_TRUE(GetServices().empty());
}

TEST_F(WiFiProviderTest, OnEndpointAddedToMockService) {
  // The previous test allowed the provider to create its own "real"
  // WiFiServices, which hides some of what we can test with mock
  // services.  Re-do an add-endpoint operation by seeding the provider
  // with a mock service.
  provider_.Start();
  const string ssid0("an_ssid");
  const vector<uint8_t> ssid0_bytes(ssid0.begin(), ssid0.end());
  MockWiFiServiceRefPtr service0 = AddMockService(ssid0_bytes,
                                                  kModeManaged,
                                                  kSecurityNone,
                                                  false);
  const string ssid1("another_ssid");
  const vector<uint8_t> ssid1_bytes(ssid1.begin(), ssid1.end());
  MockWiFiServiceRefPtr service1 = AddMockService(ssid1_bytes,
                                                  kModeManaged,
                                                  kSecurityNone,
                                                  false);
  EXPECT_EQ(service0.get(), FindService(ssid0_bytes,
                                        kModeManaged,
                                        kSecurityNone).get());
  WiFiEndpointRefPtr endpoint0 = MakeEndpoint(ssid0, "00:00:00:00:00:00", 0, 0);
  EXPECT_CALL(manager_, RegisterService(_)).Times(0);
  EXPECT_CALL(manager_, UpdateService(RefPtrMatch(service0))).Times(1);
  EXPECT_CALL(*service0, AddEndpoint(RefPtrMatch(endpoint0))).Times(1);
  EXPECT_CALL(*service1, AddEndpoint(_)).Times(0);
  provider_.OnEndpointAdded(endpoint0);
  Mock::VerifyAndClearExpectations(&manager_);
  Mock::VerifyAndClearExpectations(service0.get());
  Mock::VerifyAndClearExpectations(service1.get());

  WiFiEndpointRefPtr endpoint1 = MakeEndpoint(ssid0, "00:00:00:00:00:01", 0, 0);
  EXPECT_CALL(manager_, RegisterService(_)).Times(0);
  EXPECT_CALL(manager_, UpdateService(RefPtrMatch(service0))).Times(1);
  EXPECT_CALL(*service0, AddEndpoint(RefPtrMatch(endpoint1))).Times(1);
  EXPECT_CALL(*service1, AddEndpoint(_)).Times(0);
  provider_.OnEndpointAdded(endpoint1);
  Mock::VerifyAndClearExpectations(&manager_);
  Mock::VerifyAndClearExpectations(service0.get());
  Mock::VerifyAndClearExpectations(service1.get());

  WiFiEndpointRefPtr endpoint2 = MakeEndpoint(ssid1, "00:00:00:00:00:02", 0, 0);
  EXPECT_CALL(manager_, RegisterService(_)).Times(0);
  EXPECT_CALL(manager_, UpdateService(RefPtrMatch(service1))).Times(1);
  EXPECT_CALL(*service0, AddEndpoint(_)).Times(0);
  EXPECT_CALL(*service1, AddEndpoint(RefPtrMatch(endpoint2))).Times(1);
  provider_.OnEndpointAdded(endpoint2);
}

TEST_F(WiFiProviderTest, OnEndpointRemoved) {
  provider_.Start();
  const string ssid0("an_ssid");
  const vector<uint8_t> ssid0_bytes(ssid0.begin(), ssid0.end());
  MockWiFiServiceRefPtr service0 = AddMockService(ssid0_bytes,
                                                  kModeManaged,
                                                  kSecurityNone,
                                                  false);
  const string ssid1("another_ssid");
  const vector<uint8_t> ssid1_bytes(ssid1.begin(), ssid1.end());
  MockWiFiServiceRefPtr service1 = AddMockService(ssid1_bytes,
                                                  kModeManaged,
                                                  kSecurityNone,
                                                  false);
  EXPECT_EQ(2, GetServices().size());

  // Remove the last endpoint of a non-remembered service.
  WiFiEndpointRefPtr endpoint0 = MakeEndpoint(ssid0, "00:00:00:00:00:00", 0, 0);
  AddEndpointToService(service0, endpoint0);
  EXPECT_EQ(1, GetServiceByEndpoint().size());

  EXPECT_CALL(*service0, RemoveEndpoint(RefPtrMatch(endpoint0))).Times(1);
  EXPECT_CALL(*service1, RemoveEndpoint(_)).Times(0);
  EXPECT_CALL(*service0, HasEndpoints()).WillOnce(Return(false));
  EXPECT_CALL(*service0, IsRemembered()).WillOnce(Return(false));
  EXPECT_CALL(*service0, ResetWiFi()).Times(1);
  EXPECT_CALL(manager_, UpdateService(RefPtrMatch(service0))).Times(0);
  EXPECT_CALL(manager_, DeregisterService(RefPtrMatch(service0))).Times(1);
  provider_.OnEndpointRemoved(endpoint0);
  // Verify now, so it's clear that this happened as a result of the call
  // above, and not anything in the destructor(s).
  Mock::VerifyAndClearExpectations(&manager_);
  Mock::VerifyAndClearExpectations(service0.get());
  Mock::VerifyAndClearExpectations(service1.get());
  EXPECT_EQ(1, GetServices().size());
  EXPECT_EQ(service1.get(), GetServices().front().get());
  EXPECT_TRUE(GetServiceByEndpoint().empty());
}

TEST_F(WiFiProviderTest, OnEndpointRemovedButHasEndpoints) {
  provider_.Start();
  const string ssid0("an_ssid");
  const vector<uint8_t> ssid0_bytes(ssid0.begin(), ssid0.end());
  MockWiFiServiceRefPtr service0 = AddMockService(ssid0_bytes,
                                                  kModeManaged,
                                                  kSecurityNone,
                                                  false);
  EXPECT_EQ(1, GetServices().size());

  // Remove an endpoint of a non-remembered service.
  WiFiEndpointRefPtr endpoint0 = MakeEndpoint(ssid0, "00:00:00:00:00:00", 0, 0);
  AddEndpointToService(service0, endpoint0);
  EXPECT_EQ(1, GetServiceByEndpoint().size());

  EXPECT_CALL(*service0, RemoveEndpoint(RefPtrMatch(endpoint0))).Times(1);
  EXPECT_CALL(*service0, HasEndpoints()).WillOnce(Return(true));
  EXPECT_CALL(*service0, IsRemembered()).WillRepeatedly(Return(false));
  EXPECT_CALL(manager_, UpdateService(RefPtrMatch(service0))).Times(1);
  EXPECT_CALL(*service0, ResetWiFi()).Times(0);
  EXPECT_CALL(manager_, DeregisterService(_)).Times(0);
  provider_.OnEndpointRemoved(endpoint0);
  // Verify now, so it's clear that this happened as a result of the call
  // above, and not anything in the destructor(s).
  Mock::VerifyAndClearExpectations(&manager_);
  Mock::VerifyAndClearExpectations(service0.get());
  EXPECT_EQ(1, GetServices().size());
  EXPECT_TRUE(GetServiceByEndpoint().empty());
}

TEST_F(WiFiProviderTest, OnEndpointRemovedButIsRemembered) {
  provider_.Start();
  const string ssid0("an_ssid");
  const vector<uint8_t> ssid0_bytes(ssid0.begin(), ssid0.end());
  MockWiFiServiceRefPtr service0 = AddMockService(ssid0_bytes,
                                                  kModeManaged,
                                                  kSecurityNone,
                                                  false);
  EXPECT_EQ(1, GetServices().size());

  // Remove the last endpoint of a remembered service.
  WiFiEndpointRefPtr endpoint0 = MakeEndpoint(ssid0, "00:00:00:00:00:00", 0, 0);
  AddEndpointToService(service0, endpoint0);
  EXPECT_EQ(1, GetServiceByEndpoint().size());

  EXPECT_CALL(*service0, RemoveEndpoint(RefPtrMatch(endpoint0))).Times(1);
  EXPECT_CALL(*service0, HasEndpoints()).WillRepeatedly(Return(false));
  EXPECT_CALL(*service0, IsRemembered()).WillOnce(Return(true));
  EXPECT_CALL(manager_, UpdateService(RefPtrMatch(service0))).Times(1);
  EXPECT_CALL(*service0, ResetWiFi()).Times(0);
  EXPECT_CALL(manager_, DeregisterService(_)).Times(0);
  provider_.OnEndpointRemoved(endpoint0);
  // Verify now, so it's clear that this happened as a result of the call
  // above, and not anything in the destructor(s).
  Mock::VerifyAndClearExpectations(&manager_);
  Mock::VerifyAndClearExpectations(service0.get());
  EXPECT_EQ(1, GetServices().size());
  EXPECT_TRUE(GetServiceByEndpoint().empty());
}

TEST_F(WiFiProviderTest, OnEndpointRemovedWhileStopped) {
  // If we don't call provider_.Start(), OnEndpointRemoved should not
  // cause a crash even if a service matching the endpoint does not exist.
  const string ssid("an_ssid");
  WiFiEndpointRefPtr endpoint = MakeEndpoint(ssid, "00:00:00:00:00:00", 0, 0);
  provider_.OnEndpointRemoved(endpoint);
}

TEST_F(WiFiProviderTest, OnEndpointUpdated) {
  provider_.Start();

  // Create an endpoint and associate it with a mock service.
  const string ssid("an_ssid");
  WiFiEndpointRefPtr endpoint = MakeEndpoint(ssid, "00:00:00:00:00:00", 0, 0);

  const vector<uint8_t> ssid_bytes(ssid.begin(), ssid.end());
  MockWiFiServiceRefPtr open_service = AddMockService(ssid_bytes,
                                                      kModeManaged,
                                                      kSecurityNone,
                                                      false);
  EXPECT_CALL(*open_service, AddEndpoint(RefPtrMatch(endpoint)));
  EXPECT_CALL(manager_, UpdateService(RefPtrMatch(open_service)));
  provider_.OnEndpointAdded(endpoint);
  Mock::VerifyAndClearExpectations(open_service.get());

  // WiFiProvider is running and endpoint matches this service.
  EXPECT_CALL(*open_service, NotifyEndpointUpdated(RefPtrMatch(endpoint)));
  EXPECT_CALL(*open_service, AddEndpoint(_)).Times(0);
  provider_.OnEndpointUpdated(endpoint);
  Mock::VerifyAndClearExpectations(open_service.get());

  // If the endpoint is changed in a way that causes it to match a different
  // service, the provider should transfer the endpoint from one service to
  // the other.
  MockWiFiServiceRefPtr rsn_service = AddMockService(ssid_bytes,
                                                     kModeManaged,
                                                     kSecurityRsn,
                                                     false);
  EXPECT_CALL(*open_service, RemoveEndpoint(RefPtrMatch(endpoint)));
  // We are playing out a scenario where the open service is not removed
  // since it still claims to have more endpoints remaining.
  EXPECT_CALL(*open_service, HasEndpoints()).WillOnce(Return(true));
  EXPECT_CALL(*rsn_service, AddEndpoint(RefPtrMatch(endpoint)));
  EXPECT_CALL(manager_, UpdateService(RefPtrMatch(open_service)));
  EXPECT_CALL(manager_, UpdateService(RefPtrMatch(rsn_service)));
  endpoint->set_security_mode(kSecurityRsn);
  provider_.OnEndpointUpdated(endpoint);
}

TEST_F(WiFiProviderTest, OnEndpointUpdatedWhileStopped) {
  // If we don't call provider_.Start(), OnEndpointUpdated should not
  // cause a crash even if a service matching the endpoint does not exist.
  const string ssid("an_ssid");
  WiFiEndpointRefPtr endpoint = MakeEndpoint(ssid, "00:00:00:00:00:00", 0, 0);
  provider_.OnEndpointUpdated(endpoint);
}

TEST_F(WiFiProviderTest, OnServiceUnloaded) {
  // This function should never unregister services itself -- the Manager
  // will automatically deregister the service if OnServiceUnloaded()
  // returns true (via WiFiService::Unload()).
  EXPECT_CALL(manager_, DeregisterService(_)).Times(0);

  MockWiFiServiceRefPtr service = AddMockService(vector<uint8_t>(1, '0'),
                                                 kModeManaged,
                                                 kSecurityNone,
                                                 false);
  EXPECT_EQ(1, GetServices().size());
  EXPECT_CALL(*service, HasEndpoints()).WillOnce(Return(true));
  EXPECT_CALL(*service, ResetWiFi()).Times(0);
  EXPECT_FALSE(provider_.OnServiceUnloaded(service));
  EXPECT_EQ(1, GetServices().size());
  Mock::VerifyAndClearExpectations(service.get());

  EXPECT_CALL(*service, HasEndpoints()).WillOnce(Return(false));
  EXPECT_CALL(*service, ResetWiFi()).Times(1);
  EXPECT_TRUE(provider_.OnServiceUnloaded(service));
  // Verify now, so it's clear that this happened as a result of the call
  // above, and not anything in the destructor(s).
  Mock::VerifyAndClearExpectations(service.get());
  EXPECT_TRUE(GetServices().empty());

  Mock::VerifyAndClearExpectations(&manager_);
}

TEST_F(WiFiProviderTest, LoadAndFixupServiceEntriesDefaultProfile) {
  // We test LoadAndFixupServiceEntries indirectly since it calls a static
  // method in WiFiService.
  EXPECT_CALL(metrics_, SendEnumToUMA(
      "Network.Shill.Wifi.ServiceFixupEntries",
      Metrics::kMetricServiceFixupDefaultProfile,
      Metrics::kMetricServiceFixupMax)).Times(1);
  EXPECT_CALL(default_profile_storage_, Flush()).Times(1);
  const string kGroupId =
      StringPrintf("%s_0_0_%s_%s", kTypeWifi, kModeManaged, kSecurityNone);
  EXPECT_CALL(default_profile_storage_,
              GetString(kGroupId, _, _)).WillRepeatedly(Return(false));
  EXPECT_CALL(default_profile_storage_,
              SetString(kGroupId, _, _)).WillRepeatedly(Return(true));
  set<string> groups;
  groups.insert(kGroupId);
  EXPECT_CALL(default_profile_storage_, GetGroups())
      .WillRepeatedly(Return(groups));
  EXPECT_CALL(default_profile_storage_, GetStringList(WiFiProvider::kStorageId,
      StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 0), _)).
      WillOnce(Return(true));
  EXPECT_CALL(default_profile_storage_, GetStringList(WiFiProvider::kStorageId,
      StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 1), _)).
      WillOnce(Return(true));
  EXPECT_CALL(default_profile_storage_, GetStringList(WiFiProvider::kStorageId,
      StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 2), _)).
      WillOnce(Return(true));
  EXPECT_CALL(default_profile_storage_, GetStringList(WiFiProvider::kStorageId,
      StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 3), _)).
      WillOnce(Return(false));
  LoadAndFixupServiceEntries(default_profile_.get());
}

TEST_F(WiFiProviderTest, LoadAndFixupServiceEntriesUserProfile) {
  EXPECT_CALL(metrics_, SendEnumToUMA(
      "Network.Shill.Wifi.ServiceFixupEntries",
      Metrics::kMetricServiceFixupUserProfile,
      Metrics::kMetricServiceFixupMax)).Times(1);
  EXPECT_CALL(user_profile_storage_, Flush()).Times(1);
  const string kGroupId =
      StringPrintf("%s_0_0_%s_%s", kTypeWifi, kModeManaged, kSecurityNone);
  EXPECT_CALL(user_profile_storage_,
              GetString(kGroupId, _, _)).WillRepeatedly(Return(false));
  EXPECT_CALL(user_profile_storage_,
              SetString(kGroupId, _, _)).WillRepeatedly(Return(true));
  set<string> groups;
  groups.insert(kGroupId);
  EXPECT_CALL(user_profile_storage_, GetGroups())
      .WillRepeatedly(Return(groups));
  EXPECT_CALL(user_profile_storage_, GetStringList(_, _, _)).Times(0);
  LoadAndFixupServiceEntries(user_profile_.get());
}

TEST_F(WiFiProviderTest, LoadAndFixupServiceEntriesNothingToDo) {
  EXPECT_CALL(metrics_, SendEnumToUMA(_, _, _)).Times(0);
  EXPECT_CALL(default_profile_storage_, Flush()).Times(0);
  const string kGroupId =
      StringPrintf("%s_0_0_%s_%s", kTypeWifi, kModeManaged, kSecurityNone);
  EXPECT_CALL(default_profile_storage_,
              GetString(kGroupId, _, _)).WillRepeatedly(Return(true));
  set<string> groups;
  groups.insert(kGroupId);
  EXPECT_CALL(default_profile_storage_, GetGroups()).WillOnce(Return(groups));
  EXPECT_CALL(default_profile_storage_, GetStringList(WiFiProvider::kStorageId,
      StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 0), _)).
      WillOnce(Return(true));
  EXPECT_CALL(default_profile_storage_, GetStringList(WiFiProvider::kStorageId,
      StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 1), _)).
      WillOnce(Return(true));
  EXPECT_CALL(default_profile_storage_, GetStringList(WiFiProvider::kStorageId,
      StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 2), _)).
      WillOnce(Return(true));
  EXPECT_CALL(default_profile_storage_, GetStringList(WiFiProvider::kStorageId,
      StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 3), _)).
      WillOnce(Return(false));
  LoadAndFixupServiceEntries(default_profile_.get());
}

TEST_F(WiFiProviderTest, GetHiddenSSIDList) {
  EXPECT_TRUE(provider_.GetHiddenSSIDList().empty());
  const vector<uint8_t> ssid0(1, '0');
  AddMockService(ssid0, kModeManaged, kSecurityNone, false);
  EXPECT_TRUE(provider_.GetHiddenSSIDList().empty());

  const vector<uint8_t> ssid1(1, '1');
  MockWiFiServiceRefPtr service1 = AddMockService(ssid1,
                                                  kModeManaged,
                                                  kSecurityNone,
                                                  true);
  EXPECT_CALL(*service1, IsRemembered()).WillRepeatedly(Return(false));
  EXPECT_TRUE(provider_.GetHiddenSSIDList().empty());

  const vector<uint8_t> ssid2(1, '2');
  MockWiFiServiceRefPtr service2 = AddMockService(ssid2,
                                                  kModeManaged,
                                                  kSecurityNone,
                                                  true);
  EXPECT_CALL(*service2, IsRemembered()).WillRepeatedly(Return(true));
  ByteArrays ssid_list = provider_.GetHiddenSSIDList();

  EXPECT_EQ(1, ssid_list.size());
  EXPECT_TRUE(ssid_list[0] == ssid2);

  const vector<uint8_t> ssid3(1, '3');
  MockWiFiServiceRefPtr service3 = AddMockService(ssid3,
                                                  kModeManaged,
                                                  kSecurityNone,
                                                  false);
  EXPECT_CALL(*service2, IsRemembered()).WillRepeatedly(Return(true));

  ssid_list = provider_.GetHiddenSSIDList();
  EXPECT_EQ(1, ssid_list.size());
  EXPECT_TRUE(ssid_list[0] == ssid2);

  const vector<uint8_t> ssid4(1, '4');
  MockWiFiServiceRefPtr service4 = AddMockService(ssid4,
                                                  kModeManaged,
                                                  kSecurityNone,
                                                  true);
  EXPECT_CALL(*service4, IsRemembered()).WillRepeatedly(Return(true));

  ssid_list = provider_.GetHiddenSSIDList();
  EXPECT_EQ(2, ssid_list.size());
  EXPECT_TRUE(ssid_list[0] == ssid2);
  EXPECT_TRUE(ssid_list[1] == ssid4);
}

TEST_F(WiFiProviderTest, StringListToFrequencyMap) {
  vector<string> strings;
  BuildFreqCountStrings(&strings);
  WiFiProvider::ConnectFrequencyMap frequencies_result;
  time_t days = WiFiProvider::StringListToFrequencyMap(strings,
                                                       &frequencies_result);

  WiFiProvider::ConnectFrequencyMap frequencies_expect;
  BuildFreqCountMap(&frequencies_expect);
  EXPECT_THAT(frequencies_result, ContainerEq(frequencies_expect));
  EXPECT_EQ(days, kTestDays);
}

TEST_F(WiFiProviderTest, StringListToFrequencyMapEmpty) {
  vector<string> strings;
  strings.push_back("@50");
  WiFiProvider::ConnectFrequencyMap frequencies_result;
  time_t days = WiFiProvider::StringListToFrequencyMap(strings,
                                                       &frequencies_result);
  EXPECT_TRUE(frequencies_result.empty());
  EXPECT_EQ(days, 50);
}

TEST_F(WiFiProviderTest, FrequencyMapToStringList) {
  WiFiProvider::ConnectFrequencyMap frequencies;
  BuildFreqCountMap(&frequencies);
  vector<string> strings_result;
  WiFiProvider::FrequencyMapToStringList(kTestDays, frequencies,
                                         &strings_result);

  vector<string> strings_expect;
  BuildFreqCountStrings(&strings_expect);
  EXPECT_THAT(strings_result, ContainerEq(strings_expect));
}

TEST_F(WiFiProviderTest, FrequencyMapToStringListEmpty) {
  WiFiProvider::ConnectFrequencyMap frequencies;
  vector<string> strings_result;
  WiFiProvider::FrequencyMapToStringList(kTestDays, frequencies,
                                         &strings_result);
  EXPECT_EQ(1, strings_result.size());
  EXPECT_EQ(*strings_result.begin(), "@20");
}

TEST_F(WiFiProviderTest, FrequencyMapBasicAging) {
  const time_t kThisWeek = kFirstWeek +
      WiFiProvider::kWeeksToKeepFrequencyCounts - 1;
  LoadConnectCountByFrequency(kThisWeek * kSecondsPerWeek);

  // Make sure we have data for all 3 blocks.
  WiFiProvider::ConnectFrequencyMap expected;
  expected[5001] = 2;
  expected[5002] = 2;
  expected[6001] = 1;
  expected[6002] = 2;
  expected[7001] = 1;
  expected[7002] = 2;
  EXPECT_THAT(provider_.connect_count_by_frequency_, ContainerEq(expected));

  // And, then, make sure we output the expected blocks of data.
  EXPECT_CALL(
      default_profile_storage_,
      SetStringList(WiFiProvider::kStorageId, _,
                    Eq(profile_frequency_data_[
                        StringPrintf(
                            "%s%d", WiFiProvider::kStorageFrequencies, 0)])));
  EXPECT_CALL(
      default_profile_storage_,
      SetStringList(WiFiProvider::kStorageId, _,
                    Eq(profile_frequency_data_[
                        StringPrintf(
                            "%s%d", WiFiProvider::kStorageFrequencies, 1)])));
  EXPECT_CALL(
      default_profile_storage_,
      SetStringList(WiFiProvider::kStorageId, _,
                    Eq(profile_frequency_data_[
                        StringPrintf(
                            "%s%d", WiFiProvider::kStorageFrequencies, 2)])));
  vector<string> frequencies;
  frequencies.push_back(base::StringPrintf("@%" PRIu64,
                                           static_cast<uint64_t>(kThisWeek)));
  EXPECT_CALL(
      default_profile_storage_,
      SetStringList(WiFiProvider::kStorageId, _, Eq(frequencies))).Times(0);
  Save();
}

TEST_F(WiFiProviderTest, FrequencyMapAgingIllegalDay) {
  provider_.time_ = &time_;
  const time_t kThisWeek = kFirstWeek +
      WiFiProvider::kWeeksToKeepFrequencyCounts - 1;
  const time_t kThisWeekSeconds = kThisWeek * kSecondsPerWeek;
  EXPECT_CALL(time_, GetSecondsSinceEpoch()).WillOnce(Return(kThisWeekSeconds));
  const string kGroupId =
      StringPrintf("%s_0_0_%s_%s", kTypeWifi, kModeManaged, kSecurityNone);
  EXPECT_CALL(default_profile_storage_,
              GetString(kGroupId, _, _)).WillRepeatedly(Return(true));
  set<string> groups;
  groups.insert(kGroupId);
  // Instead of block[1], return a block without the date.
  EXPECT_CALL(default_profile_storage_, GetGroups()).WillOnce(Return(groups));
  EXPECT_CALL(default_profile_storage_, GetStringList(WiFiProvider::kStorageId,
      StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 0), _)).
      WillOnce(Invoke(this, &WiFiProviderTest::GetStringList));
  EXPECT_CALL(default_profile_storage_, GetStringList(WiFiProvider::kStorageId,
      StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 1), _)).
      WillOnce(Invoke(this, &WiFiProviderTest::GetIllegalDayStringList));
  EXPECT_CALL(default_profile_storage_, GetStringList(WiFiProvider::kStorageId,
      StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 2), _)).
      WillOnce(Invoke(this, &WiFiProviderTest::GetStringList));
  EXPECT_CALL(default_profile_storage_, GetStringList(WiFiProvider::kStorageId,
      StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 3), _)).
      WillOnce(Invoke(this, &WiFiProviderTest::GetStringList));

  LoadAndFixupServiceEntries(default_profile_.get());

  // Verify that the received information only includes block[0] and block[2].
  WiFiProvider::ConnectFrequencyMap expected;
  expected[5001] = 1;
  expected[5002] = 2;
  expected[7001] = 1;
  expected[7002] = 2;
  EXPECT_THAT(provider_.connect_count_by_frequency_, ContainerEq(expected));

  // And, then, make sure we output the expected blocks of data.
  EXPECT_CALL(
      default_profile_storage_,
      SetStringList(WiFiProvider::kStorageId, _,
                    Eq(profile_frequency_data_[
                        StringPrintf(
                            "%s%d", WiFiProvider::kStorageFrequencies, 0)])));
  EXPECT_CALL(
      default_profile_storage_,
      SetStringList(WiFiProvider::kStorageId, _,
                    Eq(profile_frequency_data_[
                        StringPrintf(
                            "%s%d", WiFiProvider::kStorageFrequencies, 1)]))).
      Times(0);
  EXPECT_CALL(
      default_profile_storage_,
      SetStringList(WiFiProvider::kStorageId, _,
                    Eq(profile_frequency_data_[
                        StringPrintf(
                            "%s%d", WiFiProvider::kStorageFrequencies, 2)])));
  vector<string> frequencies;
  frequencies.push_back(base::StringPrintf("@%" PRIu64,
                                           static_cast<uint64_t>(kThisWeek)));
  EXPECT_CALL(default_profile_storage_,
              SetStringList(WiFiProvider::kStorageId, _, Eq(frequencies)))
      .Times(0);
  Save();
}

TEST_F(WiFiProviderTest, IncrementConnectCount) {
  const time_t kThisWeek = kFirstWeek +
      WiFiProvider::kWeeksToKeepFrequencyCounts - 1;
  const time_t kThisWeekSeconds = kThisWeek * kSecondsPerWeek;
  LoadConnectCountByFrequency(kThisWeekSeconds);

  EXPECT_CALL(time_, GetSecondsSinceEpoch()).WillOnce(Return(kThisWeekSeconds));
  EXPECT_CALL(manager_, UpdateWiFiProvider());
  EXPECT_CALL(metrics_, SendToUMA(Metrics::kMetricFrequenciesConnectedEver,
                                  _, _, _, _));
  time_t newest_week_at_start =
      provider_.connect_count_by_frequency_dated_.crbegin()->first;
  provider_.IncrementConnectCount(6002);

  // Make sure we have data for all 3 blocks.
  WiFiProvider::ConnectFrequencyMap expected;
  expected[5001] = 2;
  expected[5002] = 2;
  expected[6001] = 1;
  expected[6002] = 3;
  expected[7001] = 1;
  expected[7002] = 2;
  EXPECT_THAT(provider_.connect_count_by_frequency_, ContainerEq(expected));
  // Make sure we didn't delete the oldest block.
  EXPECT_TRUE(base::ContainsKey(provider_.connect_count_by_frequency_dated_,
                                kFirstWeek));
  // Make sure we didn't create a new block.
  time_t newest_week_at_end =
      provider_.connect_count_by_frequency_dated_.crbegin()->first;
  EXPECT_EQ(newest_week_at_start, newest_week_at_end);
}

TEST_F(WiFiProviderTest, IncrementConnectCountCreateNew) {
  time_t this_week = kFirstWeek + WiFiProvider::kWeeksToKeepFrequencyCounts - 1;
  LoadConnectCountByFrequency(this_week * kSecondsPerWeek);

  this_week += 2;
  EXPECT_CALL(time_, GetSecondsSinceEpoch()).
      WillOnce(Return(this_week * kSecondsPerWeek));
  EXPECT_CALL(manager_, UpdateWiFiProvider());
  EXPECT_CALL(metrics_, SendToUMA(Metrics::kMetricFrequenciesConnectedEver,
                                  _, _, _, _));
  time_t newest_week_at_start =
      provider_.connect_count_by_frequency_dated_.crbegin()->first;
  provider_.IncrementConnectCount(6001);

  // Make sure we have data for newest 2 blocks (only).
  WiFiProvider::ConnectFrequencyMap expected;
  expected[5001] = 1;
  expected[6001] = 2;
  expected[6002] = 2;
  expected[7001] = 1;
  expected[7002] = 2;
  EXPECT_THAT(provider_.connect_count_by_frequency_, ContainerEq(expected));
  // Verify that the oldest block is gone.
  EXPECT_FALSE(base::ContainsKey(provider_.connect_count_by_frequency_dated_,
                                 kFirstWeek));
  // Make sure we created a new block and that it is for the current week.
  time_t newest_week_at_end =
      provider_.connect_count_by_frequency_dated_.crbegin()->first;
  EXPECT_NE(newest_week_at_start, newest_week_at_end);
  EXPECT_TRUE(base::ContainsKey(provider_.connect_count_by_frequency_dated_,
                                this_week));
}

TEST_F(WiFiProviderTest, ReportAutoConnectableServices) {
  MockWiFiServiceRefPtr service0 = AddMockService(vector<uint8_t>(1, '0'),
                                                  kModeManaged,
                                                  kSecurityNone,
                                                  false);
  MockWiFiServiceRefPtr service1 = AddMockService(vector<uint8_t>(1, '1'),
                                                  kModeManaged,
                                                  kSecurityNone,
                                                  false);
  service0->EnableAndRetainAutoConnect();
  service0->SetConnectable(true);
  service1->EnableAndRetainAutoConnect();
  service1->SetConnectable(true);

  EXPECT_CALL(*service0, IsAutoConnectable(_))
      .WillOnce(Return(true))
      .WillOnce(Return(false));
  EXPECT_CALL(*service1, IsAutoConnectable(_))
      .WillRepeatedly(Return(false));

  // With 1 auto connectable service.
  EXPECT_CALL(metrics_, NotifyWifiAutoConnectableServices(1));
  provider_.ReportAutoConnectableServices();

  // With no auto connectable service.
  EXPECT_CALL(metrics_, NotifyWifiAutoConnectableServices(_)).Times(0);
  provider_.ReportAutoConnectableServices();
}

TEST_F(WiFiProviderTest, NumAutoConnectableServices) {
  MockWiFiServiceRefPtr service0 = AddMockService(
      vector<uint8_t>(1, '0'), kModeManaged, kSecurityNone, false);
  MockWiFiServiceRefPtr service1 = AddMockService(
      vector<uint8_t>(1, '1'), kModeManaged, kSecurityNone, false);
  service0->EnableAndRetainAutoConnect();
  service0->SetConnectable(true);
  service1->EnableAndRetainAutoConnect();
  service1->SetConnectable(true);

  EXPECT_CALL(*service0, IsAutoConnectable(_))
      .WillOnce(Return(true))
      .WillOnce(Return(false));
  EXPECT_CALL(*service1, IsAutoConnectable(_)).WillRepeatedly(Return(true));

  // 2 auto-connectable services.
  EXPECT_EQ(2, provider_.NumAutoConnectableServices());

  // 1 auto-connectable service.
  EXPECT_EQ(1, provider_.NumAutoConnectableServices());
}

TEST_F(WiFiProviderTest, GetSsidsConfiguredForAutoConnect) {
  vector<uint8_t> ssid0(3, '0');
  vector<uint8_t> ssid1(5, '1');
  ByteString ssid0_bytes(ssid0);
  ByteString ssid1_bytes(ssid1);
  MockWiFiServiceRefPtr service0 =
      AddMockService(ssid0, kModeManaged, kSecurityNone, false);
  MockWiFiServiceRefPtr service1 =
      AddMockService(ssid1, kModeManaged, kSecurityNone, false);
  // 2 services configured for auto-connect.
  service0->SetAutoConnect(true);
  service1->SetAutoConnect(true);
  vector<ByteString> service_list_0 =
      provider_.GetSsidsConfiguredForAutoConnect();
  EXPECT_EQ(2, service_list_0.size());
  EXPECT_TRUE(ssid0_bytes.Equals(service_list_0[0]));
  EXPECT_TRUE(ssid1_bytes.Equals(service_list_0[1]));

  // 1 service configured for auto-connect.
  service0->SetAutoConnect(false);
  service1->SetAutoConnect(true);
  vector<ByteString> service_list_1 =
      provider_.GetSsidsConfiguredForAutoConnect();
  EXPECT_EQ(1, service_list_1.size());
  EXPECT_TRUE(ssid1_bytes.Equals(service_list_1[0]));
}

}  // namespace shill
