// Copyright 2018 The Chromium OS 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 "shill/cellular/cellular_service.h"

#include <chromeos/dbus/service_constants.h>
#include <gtest/gtest.h>

#include "shill/cellular/cellular_capability.h"
#include "shill/cellular/mock_cellular.h"
#include "shill/cellular/mock_mobile_operator_info.h"
#include "shill/cellular/mock_modem_info.h"
#include "shill/fake_store.h"
#include "shill/mock_adaptors.h"
#include "shill/mock_profile.h"
#include "shill/service_property_change_test.h"

using std::string;
using testing::_;
using testing::AnyNumber;
using testing::Mock;
using testing::NiceMock;
using testing::Return;

namespace shill {

namespace {
const char kImsi[] = "111222123456789";
const char kIccid[] = "1234567890000";
}  // namespace

class CellularServiceTest : public testing::Test {
 public:
  CellularServiceTest()
      : modem_info_(nullptr, &dispatcher_, nullptr, nullptr),
        adaptor_(nullptr) {
    Service::SetNextSerialNumberForTesting(0);
  }
  ~CellularServiceTest() override { adaptor_ = nullptr; }

  void SetUp() override {
    // Many tests set service properties which call Manager.UpdateService().
    EXPECT_CALL(*modem_info_.mock_manager(), UpdateService(_))
        .Times(AnyNumber());
    device_ = new MockCellular(&modem_info_, "usb0", kAddress, 3,
                               Cellular::kTypeCdma, "", RpcIdentifier(""));
    // CellularService expects an IMSI and SIM ID be set in the Device.
    device_->set_imsi(kImsi);
    device_->set_iccid(kIccid);
    service_ = new CellularService(modem_info_.manager(), kImsi, kIccid,
                                   device_->GetSimCardId());
    service_->SetDevice(device_.get());
    adaptor_ = static_cast<ServiceMockAdaptor*>(service_->adaptor());

    storage_id_ = service_->GetStorageIdentifier();
    storage_.SetString(storage_id_, CellularService::kStorageType,
                       kTypeCellular);
    storage_.SetString(storage_id_, CellularService::kStorageIccid, kIccid);
    storage_.SetString(storage_id_, CellularService::kStorageImsi, kImsi);
  }

 protected:
  static const char kAddress[];

  string GetFriendlyName() const { return service_->friendly_name(); }
  bool IsAutoConnectable(const char** reason) const {
    return service_->IsAutoConnectable(reason);
  }
  bool SetAutoConnectFull(bool connect) {
    return service_->SetAutoConnectFull(connect, /*error=*/nullptr);
  }

  EventDispatcher dispatcher_;
  MockModemInfo modem_info_;
  scoped_refptr<MockCellular> device_;
  CellularServiceRefPtr service_;
  ServiceMockAdaptor* adaptor_;  // Owned by |service_|.
  std::string storage_id_;
  FakeStore storage_;
};

const char CellularServiceTest::kAddress[] = "000102030405";

TEST_F(CellularServiceTest, Constructor) {
  EXPECT_TRUE(service_->connectable());
}

TEST_F(CellularServiceTest, SetNetworkTechnology) {
  EXPECT_CALL(*adaptor_, EmitStringChanged(kNetworkTechnologyProperty,
                                           kNetworkTechnologyUmts));
  EXPECT_TRUE(service_->network_technology().empty());
  service_->SetNetworkTechnology(kNetworkTechnologyUmts);
  EXPECT_EQ(kNetworkTechnologyUmts, service_->network_technology());
  service_->SetNetworkTechnology(kNetworkTechnologyUmts);
}

TEST_F(CellularServiceTest, LogName) {
  EXPECT_EQ("cellular_0", service_->log_name());
  service_->SetNetworkTechnology(kNetworkTechnologyUmts);
  EXPECT_EQ("cellular_UMTS_0", service_->log_name());
  service_->SetNetworkTechnology(kNetworkTechnologyGsm);
  EXPECT_EQ("cellular_GSM_0", service_->log_name());
  service_->SetNetworkTechnology(kNetworkTechnologyLte);
  EXPECT_EQ("cellular_LTE_0", service_->log_name());
}

TEST_F(CellularServiceTest, SetRoamingState) {
  EXPECT_CALL(*adaptor_,
              EmitStringChanged(kRoamingStateProperty, kRoamingStateHome));
  EXPECT_TRUE(service_->roaming_state().empty());
  service_->SetRoamingState(kRoamingStateHome);
  EXPECT_EQ(kRoamingStateHome, service_->roaming_state());
  service_->SetRoamingState(kRoamingStateHome);
}

TEST_F(CellularServiceTest, SetServingOperator) {
  static const char kCode[] = "123456";
  static const char kName[] = "Some Cellular Operator";
  Stringmap test_operator;
  service_->SetServingOperator(test_operator);
  test_operator[kOperatorCodeKey] = kCode;
  test_operator[kOperatorNameKey] = kName;
  EXPECT_CALL(*adaptor_, EmitStringmapChanged(kServingOperatorProperty, _));
  service_->SetServingOperator(test_operator);
  const Stringmap& serving_operator = service_->serving_operator();
  ASSERT_NE(serving_operator.end(), serving_operator.find(kOperatorCodeKey));
  ASSERT_NE(serving_operator.end(), serving_operator.find(kOperatorNameKey));
  EXPECT_EQ(kCode, serving_operator.find(kOperatorCodeKey)->second);
  EXPECT_EQ(kName, serving_operator.find(kOperatorNameKey)->second);
  Mock::VerifyAndClearExpectations(adaptor_);
  EXPECT_CALL(*adaptor_, EmitStringmapChanged(kServingOperatorProperty, _))
      .Times(0);
  service_->SetServingOperator(serving_operator);
}

TEST_F(CellularServiceTest, SetOLP) {
  const char kMethod[] = "GET";
  const char kURL[] = "payment.url";
  const char kPostData[] = "post_man";
  Stringmap olp;

  service_->SetOLP("", "", "");
  olp = service_->olp();  // Copy to simplify assertions below.
  EXPECT_EQ("", olp[kPaymentPortalURL]);
  EXPECT_EQ("", olp[kPaymentPortalMethod]);
  EXPECT_EQ("", olp[kPaymentPortalPostData]);

  EXPECT_CALL(*adaptor_, EmitStringmapChanged(kPaymentPortalProperty, _));
  service_->SetOLP(kURL, kMethod, kPostData);
  olp = service_->olp();  // Copy to simplify assertions below.
  EXPECT_EQ(kURL, olp[kPaymentPortalURL]);
  EXPECT_EQ(kMethod, olp[kPaymentPortalMethod]);
  EXPECT_EQ(kPostData, olp[kPaymentPortalPostData]);
}

TEST_F(CellularServiceTest, SetUsageURL) {
  static const char kUsageURL[] = "usage.url";
  EXPECT_CALL(*adaptor_, EmitStringChanged(kUsageURLProperty, kUsageURL));
  EXPECT_TRUE(service_->usage_url().empty());
  service_->SetUsageURL(kUsageURL);
  EXPECT_EQ(kUsageURL, service_->usage_url());
  service_->SetUsageURL(kUsageURL);
}

TEST_F(CellularServiceTest, SetApn) {
  static const char kApn[] = "TheAPN";
  static const char kUsername[] = "commander.data";
  ProfileRefPtr profile(new NiceMock<MockProfile>(modem_info_.manager()));
  service_->set_profile(profile);
  Error error;
  Stringmap testapn;
  testapn[kApnProperty] = kApn;
  testapn[kApnUsernameProperty] = kUsername;
  EXPECT_CALL(*adaptor_, EmitStringmapChanged(kCellularApnProperty, _));
  service_->SetApn(testapn, &error);
  EXPECT_TRUE(error.IsSuccess());
  Stringmap resultapn = service_->GetApn(&error);
  EXPECT_TRUE(error.IsSuccess());
  EXPECT_EQ(2, resultapn.size());
  Stringmap::const_iterator it = resultapn.find(kApnProperty);
  EXPECT_TRUE(it != resultapn.end() && it->second == kApn);
  it = resultapn.find(kApnUsernameProperty);
  EXPECT_TRUE(it != resultapn.end() && it->second == kUsername);
  EXPECT_NE(nullptr, service_->GetUserSpecifiedApn());
}

TEST_F(CellularServiceTest, ClearApn) {
  static const char kApn[] = "TheAPN";
  static const char kUsername[] = "commander.data";
  ProfileRefPtr profile(new NiceMock<MockProfile>(modem_info_.manager()));
  service_->set_profile(profile);
  Error error;
  // Set up an APN to make sure that it later gets cleared.
  Stringmap testapn;
  testapn[kApnProperty] = kApn;
  testapn[kApnUsernameProperty] = kUsername;
  EXPECT_CALL(*adaptor_, EmitStringmapChanged(kCellularApnProperty, _));
  service_->SetApn(testapn, &error);
  Stringmap resultapn = service_->GetApn(&error);
  ASSERT_TRUE(error.IsSuccess());
  ASSERT_EQ(2, service_->GetApn(&error).size());

  Stringmap emptyapn;
  EXPECT_CALL(*adaptor_, EmitStringmapChanged(kCellularLastGoodApnProperty, _))
      .Times(0);
  EXPECT_CALL(*adaptor_, EmitStringmapChanged(kCellularApnProperty, _))
      .Times(1);
  service_->SetApn(emptyapn, &error);
  EXPECT_TRUE(error.IsSuccess());
  resultapn = service_->GetApn(&error);
  EXPECT_TRUE(resultapn.empty());
  EXPECT_EQ(nullptr, service_->GetUserSpecifiedApn());
}

TEST_F(CellularServiceTest, LastGoodApn) {
  static const char kApn[] = "TheAPN";
  static const char kUsername[] = "commander.data";
  ProfileRefPtr profile(new NiceMock<MockProfile>(modem_info_.manager()));
  service_->set_profile(profile);
  Stringmap testapn;
  testapn[kApnProperty] = kApn;
  testapn[kApnUsernameProperty] = kUsername;
  EXPECT_CALL(*adaptor_, EmitStringmapChanged(kCellularLastGoodApnProperty, _));
  service_->SetLastGoodApn(testapn);
  Stringmap* resultapn = service_->GetLastGoodApn();
  ASSERT_NE(nullptr, resultapn);
  EXPECT_EQ(2, resultapn->size());
  EXPECT_EQ(kApn, (*resultapn)[kApnProperty]);
  EXPECT_EQ(kUsername, (*resultapn)[kApnUsernameProperty]);

  // Now set the user-specified APN, and check that LastGoodApn is preserved.
  Stringmap userapn;
  userapn[kApnProperty] = kApn;
  userapn[kApnUsernameProperty] = kUsername;
  EXPECT_CALL(*adaptor_, EmitStringmapChanged(kCellularApnProperty, _));
  Error error;
  service_->SetApn(userapn, &error);

  ASSERT_NE(nullptr, service_->GetLastGoodApn());
  EXPECT_EQ(2, resultapn->size());
  EXPECT_EQ(kApn, (*resultapn)[kApnProperty]);
  EXPECT_EQ(kUsername, (*resultapn)[kApnUsernameProperty]);
}

TEST_F(CellularServiceTest, IsAutoConnectable) {
  // This test assumes AutoConnect is not disabled by policy.
  EXPECT_CALL(*modem_info_.mock_manager(), IsTechnologyAutoConnectDisabled(_))
      .WillRepeatedly(Return(false));

  const char* reason = nullptr;

  // Auto-connect should be suppressed if the device is not running.
  device_->running_ = false;
  EXPECT_FALSE(IsAutoConnectable(&reason));
  EXPECT_STREQ(CellularService::kAutoConnDeviceDisabled, reason);

  device_->running_ = true;

  // If we're in a process of activation, don't auto-connect.
  EXPECT_CALL(*modem_info_.mock_pending_activation_store(),
              GetActivationState(_, _))
      .WillOnce(Return(PendingActivationStore::kStatePending));
  EXPECT_FALSE(IsAutoConnectable(&reason));
  EXPECT_STREQ(CellularService::kAutoConnActivating, reason);
  EXPECT_CALL(*modem_info_.mock_pending_activation_store(),
              GetActivationState(_, _))
      .WillRepeatedly(Return(PendingActivationStore::kStateActivated));

  // Auto-connect should be suppressed if we're out of credits.
  service_->NotifySubscriptionStateChanged(SubscriptionState::kOutOfCredits);
  EXPECT_FALSE(IsAutoConnectable(&reason));
  EXPECT_STREQ(CellularService::kAutoConnOutOfCredits, reason);
  service_->NotifySubscriptionStateChanged(SubscriptionState::kProvisioned);

  // A PPP authentication failure means the Service is not auto-connectable.
  service_->SetFailure(Service::kFailurePPPAuth);
  EXPECT_FALSE(IsAutoConnectable(&reason));
  EXPECT_STREQ(CellularService::kAutoConnBadPPPCredentials, reason);

  // Reset failure state, to make the Service auto-connectable again.
  service_->SetState(Service::kStateIdle);
  EXPECT_TRUE(IsAutoConnectable(&reason));

  // The following test cases are copied from ServiceTest.IsAutoConnectable

  service_->SetConnectable(true);
  EXPECT_TRUE(IsAutoConnectable(&reason));

  // We should not auto-connect to a Service that a user has
  // deliberately disconnected.
  Error error;
  service_->UserInitiatedDisconnect("RPC", &error);
  EXPECT_FALSE(IsAutoConnectable(&reason));
  EXPECT_STREQ(Service::kAutoConnExplicitDisconnect, reason);

  // If the Service is reloaded, it is eligible for auto-connect again.
  EXPECT_TRUE(service_->Load(&storage_));
  EXPECT_TRUE(IsAutoConnectable(&reason));

  // A non-user initiated Disconnect doesn't change anything.
  service_->Disconnect(&error, "in test");
  EXPECT_TRUE(IsAutoConnectable(&reason));

  // A resume also re-enables auto-connect.
  service_->UserInitiatedDisconnect("RPC", &error);
  EXPECT_FALSE(IsAutoConnectable(&reason));
  service_->OnAfterResume();
  EXPECT_TRUE(IsAutoConnectable(&reason));

  service_->SetState(Service::kStateConnected);
  EXPECT_FALSE(IsAutoConnectable(&reason));
  EXPECT_STREQ(Service::kAutoConnConnected, reason);

  service_->SetState(Service::kStateAssociating);
  EXPECT_FALSE(IsAutoConnectable(&reason));
  EXPECT_STREQ(Service::kAutoConnConnecting, reason);
}

TEST_F(CellularServiceTest, LoadResetsPPPAuthFailure) {
  const string kDefaultUser;
  const string kDefaultPass;
  const string kNewUser("new-username");
  const string kNewPass("new-password");
  for (const auto change_username : {false, true}) {
    for (const auto change_password : {false, true}) {
      service_->ppp_username_ = kDefaultUser;
      service_->ppp_password_ = kDefaultPass;
      service_->SetFailure(Service::kFailurePPPAuth);
      EXPECT_TRUE(service_->IsFailed());
      EXPECT_EQ(Service::kFailurePPPAuth, service_->failure());
      if (change_username) {
        storage_.SetString(storage_id_, CellularService::kStoragePPPUsername,
                           kNewUser);
      }
      if (change_password) {
        storage_.SetString(storage_id_, CellularService::kStoragePPPPassword,
                           kNewPass);
      }
      EXPECT_TRUE(service_->Load(&storage_));
      if (change_username || change_password) {
        EXPECT_NE(Service::kFailurePPPAuth, service_->failure());
      } else {
        EXPECT_EQ(Service::kFailurePPPAuth, service_->failure());
      }
    }
  }
}

// The default storage_identifier_ will be {kCellular}_{kIccid}, however older
// profile/storage entries may use a different identifier. This sets up an entry
// with a matching ICCID but an arbitrary storage id and ensures that the older
// storage_identifer_ value is set.
TEST_F(CellularServiceTest, LoadFromProfileMatchingIccid) {
  string initial_storage_id = storage_id_;
  string matching_storage_id = "another-storage-id";
  storage_.DeleteGroup(initial_storage_id);
  storage_.SetString(matching_storage_id, CellularService::kStorageType,
                     kTypeCellular);
  storage_.SetString(matching_storage_id, CellularService::kStorageIccid,
                     kIccid);
  storage_.SetString(matching_storage_id, CellularService::kStorageImsi, kImsi);

  EXPECT_TRUE(service_->IsLoadableFrom(storage_));
  EXPECT_TRUE(service_->Load(&storage_));
  EXPECT_EQ(matching_storage_id, service_->GetStorageIdentifier());
}

TEST_F(CellularServiceTest, LoadFromFirstOfMultipleMatchingProfiles) {
  string initial_storage_id = storage_id_;
  string matching_storage_ids[] = {"another-storage-id1", "another-storage-id2",
                                   "another-storage-id3"};
  storage_.DeleteGroup(initial_storage_id);
  for (auto& matching_storage_id : matching_storage_ids) {
    storage_.SetString(matching_storage_id, CellularService::kStorageType,
                       kTypeCellular);
    storage_.SetString(matching_storage_id, CellularService::kStorageIccid,
                       kIccid);
    storage_.SetString(matching_storage_id, CellularService::kStorageImsi,
                       kImsi);
  }
  EXPECT_TRUE(service_->IsLoadableFrom(storage_));
  EXPECT_TRUE(service_->Load(&storage_));
  EXPECT_EQ(matching_storage_ids[0], service_->GetStorageIdentifier());
}

TEST_F(CellularServiceTest, Save) {
  EXPECT_TRUE(service_->Save(&storage_));
  std::string iccid;
  EXPECT_TRUE(
      storage_.GetString(storage_id_, CellularService::kStorageIccid, &iccid));
  EXPECT_EQ(iccid, device_->iccid());
}

// Some of these tests duplicate signals tested above. However, it's
// convenient to have all the property change notifications documented
// (and tested) in one place.
TEST_F(CellularServiceTest, PropertyChanges) {
  TestCommonPropertyChanges(service_, adaptor_);
  TestAutoConnectPropertyChange(service_, adaptor_);

  EXPECT_CALL(*adaptor_, EmitStringChanged(kActivationTypeProperty, _));
  service_->SetActivationType(CellularService::kActivationTypeOTA);
  Mock::VerifyAndClearExpectations(adaptor_);

  EXPECT_NE(kActivationStateNotActivated, service_->activation_state());
  EXPECT_CALL(*adaptor_, EmitStringChanged(kActivationStateProperty, _));
  service_->SetActivationState(kActivationStateNotActivated);
  Mock::VerifyAndClearExpectations(adaptor_);

  string network_technology = service_->network_technology();
  EXPECT_CALL(*adaptor_, EmitStringChanged(kNetworkTechnologyProperty, _));
  service_->SetNetworkTechnology(network_technology + "and some new stuff");
  Mock::VerifyAndClearExpectations(adaptor_);

  EXPECT_CALL(*adaptor_, EmitBoolChanged(kOutOfCreditsProperty, true));
  service_->NotifySubscriptionStateChanged(SubscriptionState::kOutOfCredits);
  Mock::VerifyAndClearExpectations(adaptor_);
  EXPECT_CALL(*adaptor_, EmitBoolChanged(kOutOfCreditsProperty, false));
  service_->NotifySubscriptionStateChanged(SubscriptionState::kProvisioned);
  Mock::VerifyAndClearExpectations(adaptor_);

  string roaming_state = service_->roaming_state();
  EXPECT_CALL(*adaptor_, EmitStringChanged(kRoamingStateProperty, _));
  service_->SetRoamingState(roaming_state + "and some new stuff");
  Mock::VerifyAndClearExpectations(adaptor_);
}

// Custom property setters should return false, and make no changes, if
// the new value is the same as the old value.
TEST_F(CellularServiceTest, CustomSetterNoopChange) {
  // Test that we didn't break any setters provided by the base class.
  TestCustomSetterNoopChange(service_, modem_info_.mock_manager());

  // Test the new setter we added.
  // First set up our environment...
  static const char kApn[] = "TheAPN";
  static const char kUsername[] = "commander.data";
  Error error;
  Stringmap testapn;
  ProfileRefPtr profile(new NiceMock<MockProfile>(nullptr));
  service_->set_profile(profile);
  testapn[kApnProperty] = kApn;
  testapn[kApnUsernameProperty] = kUsername;
  // ... then set to a known value ...
  EXPECT_TRUE(service_->SetApn(testapn, &error));
  EXPECT_TRUE(error.IsSuccess());
  // ... then set to same value.
  EXPECT_FALSE(service_->SetApn(testapn, &error));
  EXPECT_TRUE(error.IsSuccess());
}

TEST_F(CellularServiceTest, IsMeteredByDefault) {
  // These services should be metered by default.
  EXPECT_TRUE(service_->IsMetered());
}

TEST_F(CellularServiceTest, SetActivationState) {
  // SetActivationState should emit a change.
  EXPECT_CALL(*adaptor_, EmitStringChanged(kActivationStateProperty,
                                           kActivationStateNotActivated));
  service_->SetActivationState(kActivationStateNotActivated);
  EXPECT_EQ(service_->activation_state(), kActivationStateNotActivated);
  EXPECT_CALL(*adaptor_, EmitStringChanged(kActivationStateProperty, _))
      .Times(AnyNumber());

  // Setting the activation state to activated should also set AutoConnect.
  EXPECT_FALSE(service_->auto_connect());
  service_->SetActivationState(kActivationStateActivated);
  EXPECT_EQ(service_->activation_state(), kActivationStateActivated);
  EXPECT_TRUE(service_->auto_connect());

  // After a client sets AutoConnect to false, setting the activation state to
  // activated should not set AutoConnect.
  SetAutoConnectFull(false);
  EXPECT_FALSE(service_->auto_connect());
  service_->SetActivationState(kActivationStateNotActivated);
  EXPECT_EQ(service_->activation_state(), kActivationStateNotActivated);
  EXPECT_FALSE(service_->auto_connect());
  service_->SetActivationState(kActivationStateActivated);
  EXPECT_EQ(service_->activation_state(), kActivationStateActivated);
  EXPECT_FALSE(service_->auto_connect());
}

}  // namespace shill
