// Copyright (c) 2012 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/wimax_service.h"

#include <string>

#include <base/strings/string_util.h>
#include <chromeos/dbus/service_constants.h>
#include <gtest/gtest.h>

#include "shill/error.h"
#include "shill/mock_adaptors.h"
#include "shill/mock_eap_credentials.h"
#include "shill/mock_manager.h"
#include "shill/mock_metrics.h"
#include "shill/mock_store.h"
#include "shill/mock_wimax.h"
#include "shill/mock_wimax_network_proxy.h"
#include "shill/mock_wimax_provider.h"
#include "shill/nice_mock_control.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;
using wimax_manager::kEAPAnonymousIdentity;
using wimax_manager::kEAPUserIdentity;
using wimax_manager::kEAPUserPassword;

namespace shill {

namespace {

const char kTestLinkName[] = "wm0";
const char kTestAddress[] = "0123456789AB";
const int kTestInterfaceIndex = 5;
const char kTestPath[] = "/org/chromium/WiMaxManager/Device/wm7";
const char kTestName[] = "Test WiMAX Network";
const char kTestNetworkId[] = "1234abcd";

}  // namespace

class WiMaxServiceTest : public testing::Test {
 public:
  WiMaxServiceTest()
      : proxy_(new MockWiMaxNetworkProxy()),
        manager_(&control_, NULL, NULL, NULL),
        metrics_(static_cast<EventDispatcher *>(NULL)),
        device_(new MockWiMax(&control_, NULL, &metrics_, &manager_,
                              kTestLinkName, kTestAddress, kTestInterfaceIndex,
                              kTestPath)),
        service_(new WiMaxService(&control_, NULL, &metrics_, &manager_)),
        eap_(new MockEapCredentials()) {
    service_->set_friendly_name(kTestName);
    service_->set_network_id(kTestNetworkId);
    service_->InitStorageIdentifier();
    service_->eap_.reset(eap_);  // Passes ownership.
  }

  virtual ~WiMaxServiceTest() {}

 protected:
  virtual void TearDown() {
    service_->device_ = NULL;
  }

  void ExpectUpdateService() {
    EXPECT_CALL(manager_, HasService(_)).WillOnce(Return(true));
    EXPECT_CALL(manager_, UpdateService(_));
  }

  void SetConnectable(bool connectable) {
    service_->connectable_ = connectable;
  }

  void SetDevice(WiMaxRefPtr device) {
    service_->SetDevice(device);
  }

  ServiceMockAdaptor *GetAdaptor() {
    return dynamic_cast<ServiceMockAdaptor *>(service_->adaptor());
  }

  scoped_ptr<MockWiMaxNetworkProxy> proxy_;
  NiceMockControl control_;
  MockManager manager_;
  NiceMock<MockMetrics> metrics_;
  scoped_refptr<MockWiMax> device_;
  WiMaxServiceRefPtr service_;
  MockEapCredentials *eap_;  // Owned by |service_|.
};

TEST_F(WiMaxServiceTest, GetConnectParameters) {
  KeyValueStore parameters;
  EXPECT_CALL(*eap_, PopulateWiMaxProperties(&parameters));
  service_->GetConnectParameters(&parameters);
}

TEST_F(WiMaxServiceTest, GetDeviceRpcId) {
  Error error;
  EXPECT_EQ("/", service_->GetDeviceRpcId(&error));
  EXPECT_EQ(Error::kNotFound, error.type());
  service_->device_ = device_;
  error.Reset();
  EXPECT_EQ(DeviceMockAdaptor::kRpcId, service_->GetDeviceRpcId(&error));
  EXPECT_TRUE(error.IsSuccess());
}

TEST_F(WiMaxServiceTest, OnSignalStrengthChanged) {
  const int kStrength = 55;
  service_->OnSignalStrengthChanged(kStrength);
  EXPECT_EQ(kStrength, service_->strength());
}

TEST_F(WiMaxServiceTest, StartStop) {
  static const char kName[] = "My WiMAX Network";
  const uint32_t kIdentifier = 0x1234abcd;
  const int kStrength = 66;
  EXPECT_FALSE(service_->connectable());
  EXPECT_FALSE(service_->IsStarted());
  EXPECT_FALSE(service_->IsVisible());
  EXPECT_EQ(0, service_->strength());
  EXPECT_FALSE(service_->proxy_.get());
  EXPECT_CALL(*proxy_, Name(_)).WillOnce(Return(kName));
  EXPECT_CALL(*proxy_, Identifier(_)).WillOnce(Return(kIdentifier));
  EXPECT_CALL(*proxy_, SignalStrength(_)).WillOnce(Return(kStrength));
  EXPECT_CALL(*proxy_, set_signal_strength_changed_callback(_));
  ServiceMockAdaptor *adaptor = GetAdaptor();
  EXPECT_CALL(*adaptor, EmitBoolChanged(kConnectableProperty, _))
     .Times(AnyNumber());
  EXPECT_CALL(*adaptor, EmitBoolChanged(kVisibleProperty, true));
  ExpectUpdateService();
  service_->need_passphrase_ = false;
  EXPECT_TRUE(service_->Start(proxy_.release()));
  EXPECT_TRUE(service_->IsStarted());
  EXPECT_TRUE(service_->IsVisible());
  EXPECT_EQ(kStrength, service_->strength());
  EXPECT_EQ(kName, service_->network_name());
  EXPECT_EQ(kTestName, service_->friendly_name());
  EXPECT_EQ(kTestNetworkId, service_->network_id());
  EXPECT_TRUE(service_->connectable());
  EXPECT_TRUE(service_->proxy_.get());

  service_->device_ = device_;
  EXPECT_CALL(*device_, OnServiceStopped(_));
  EXPECT_CALL(*adaptor, EmitBoolChanged(kVisibleProperty, false));
  ExpectUpdateService();
  service_->Stop();
  EXPECT_FALSE(service_->IsStarted());
  EXPECT_FALSE(service_->IsVisible());
  EXPECT_EQ(0, service_->strength());
  EXPECT_FALSE(service_->proxy_.get());
}

TEST_F(WiMaxServiceTest, Connectable) {
  EXPECT_TRUE(service_->Is8021x());
  EXPECT_TRUE(service_->need_passphrase_);
  EXPECT_FALSE(service_->connectable());

  EXPECT_CALL(*eap_, IsConnectableUsingPassphrase())
      .WillOnce(Return(false))
      .WillRepeatedly(Return(true));

  // No WiMaxCredentials.
  service_->OnEapCredentialsChanged();
  EXPECT_TRUE(service_->need_passphrase_);
  EXPECT_FALSE(service_->connectable());

  // Not started (no proxy).
  service_->OnEapCredentialsChanged();
  EXPECT_FALSE(service_->need_passphrase_);
  EXPECT_FALSE(service_->connectable());

  // Connectable.
  service_->proxy_.reset(proxy_.release());
  ExpectUpdateService();
  service_->OnEapCredentialsChanged();
  EXPECT_FALSE(service_->need_passphrase_);
  EXPECT_TRUE(service_->connectable());

  // Reset WimaxConnectable state.
  Mock::VerifyAndClearExpectations(eap_);
  EXPECT_CALL(*eap_, set_password(""));
  EXPECT_CALL(*eap_, IsConnectableUsingPassphrase())
      .WillRepeatedly(Return(false));
  ExpectUpdateService();
  service_->ClearPassphrase();
  EXPECT_TRUE(service_->need_passphrase_);
  EXPECT_FALSE(service_->connectable());
}

TEST_F(WiMaxServiceTest, ChangeCredResetHasEverConnected) {
  service_->has_ever_connected_ = true;
  EXPECT_TRUE(service_->has_ever_connected());
  service_->OnEapCredentialsChanged();
  EXPECT_FALSE(service_->has_ever_connected());
}

TEST_F(WiMaxServiceTest, ConvertIdentifierToNetworkId) {
  EXPECT_EQ("00000000", WiMaxService::ConvertIdentifierToNetworkId(0));
  EXPECT_EQ("abcd1234", WiMaxService::ConvertIdentifierToNetworkId(0xabcd1234));
  EXPECT_EQ("ffffffff", WiMaxService::ConvertIdentifierToNetworkId(0xffffffff));
}

TEST_F(WiMaxServiceTest, StorageIdentifier) {
  static const char kStorageId[] = "wimax_test_wimax_network_1234abcd";
  EXPECT_EQ(kStorageId, service_->GetStorageIdentifier());
  EXPECT_EQ(kStorageId,
            WiMaxService::CreateStorageIdentifier(kTestNetworkId, kTestName));
}

TEST_F(WiMaxServiceTest, Save) {
  NiceMock<MockStore> storage;
  string storage_id = service_->GetStorageIdentifier();
  EXPECT_CALL(storage, SetString(storage_id, _, _))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(storage, DeleteKey(storage_id, _)).WillRepeatedly(Return(true));
  EXPECT_CALL(storage, SetString(storage_id,
                                 WiMaxService::kStorageNetworkId,
                                 kTestNetworkId));
  EXPECT_TRUE(service_->Save(&storage));
}

TEST_F(WiMaxServiceTest, Connect) {
  // Connect but not connectable.
  Error error;
  EXPECT_FALSE(service_->connectable());
  service_->Connect(&error, "in test");
  EXPECT_EQ(Error::kOperationFailed, error.type());
  SetConnectable(true);

  // No carrier device available.
  MockWiMaxProvider provider;
  scoped_refptr<MockWiMax> null_device;
  EXPECT_CALL(manager_, wimax_provider()).WillOnce(Return(&provider));
  EXPECT_CALL(provider, SelectCarrier(_)).WillOnce(Return(null_device));
  error.Reset();
  service_->Connect(&error, "in test");
  EXPECT_EQ(Error::kNoCarrier, error.type());

  // Successful connect.
  EXPECT_CALL(manager_, wimax_provider()).WillOnce(Return(&provider));
  EXPECT_CALL(provider, SelectCarrier(_)).WillOnce(Return(device_));
  EXPECT_CALL(*device_, ConnectTo(_, _));
  error.Reset();
  service_->Connect(&error, "in test");
  EXPECT_TRUE(error.IsSuccess());

  // Connect while already connected.
  // TODO(benchan): Check for error if we populate error again after changing
  // the way that Chrome handles Error::kAlreadyConnected situation.
  service_->Connect(&error, "in test");

  // Successful disconnect.
  EXPECT_CALL(*eap_, set_password(_)).Times(0);
  EXPECT_CALL(*device_, DisconnectFrom(_, _));
  error.Reset();
  service_->Disconnect(&error, "in test");
  EXPECT_TRUE(error.IsSuccess());
  EXPECT_TRUE(service_->connectable());

  // Disconnect while not connected.
  service_->Disconnect(&error, "in test");
  EXPECT_EQ(Error::kNotConnected, error.type());
}

TEST_F(WiMaxServiceTest, Unload) {
  MockWiMaxProvider provider;
  EXPECT_CALL(manager_, wimax_provider())
      .Times(2)
      .WillRepeatedly(Return(&provider));
  EXPECT_CALL(*eap_, Reset());
  EXPECT_CALL(*eap_, set_password(""));
  EXPECT_CALL(*eap_, IsConnectableUsingPassphrase())
      .WillRepeatedly(Return(false));
  EXPECT_CALL(provider, OnServiceUnloaded(_)).WillOnce(Return(false));
  EXPECT_FALSE(service_->Unload());
  Mock::VerifyAndClearExpectations(eap_);

  EXPECT_CALL(*eap_, Reset());
  EXPECT_CALL(*eap_, set_password(""));
  EXPECT_CALL(*eap_, IsConnectableUsingPassphrase())
      .WillRepeatedly(Return(false));
  EXPECT_CALL(provider, OnServiceUnloaded(_)).WillOnce(Return(true));
  EXPECT_TRUE(service_->Unload());
}

TEST_F(WiMaxServiceTest, SetState) {
  service_->device_ = device_;
  EXPECT_EQ(Service::kStateIdle, service_->state());

  EXPECT_CALL(manager_, UpdateService(_));
  service_->SetState(Service::kStateAssociating);
  EXPECT_EQ(Service::kStateAssociating, service_->state());
  EXPECT_TRUE(service_->device_);

  EXPECT_CALL(manager_, UpdateService(_));
  service_->SetState(Service::kStateFailure);
  EXPECT_EQ(Service::kStateFailure, service_->state());
  EXPECT_FALSE(service_->device_);
}

TEST_F(WiMaxServiceTest, IsAutoConnectable) {
  EXPECT_FALSE(service_->connectable());
  const char *reason = "";

  EXPECT_FALSE(service_->IsAutoConnectable(&reason));

  MockWiMaxProvider provider;
  EXPECT_CALL(manager_, wimax_provider())
      .Times(2)
      .WillRepeatedly(Return(&provider));

  SetConnectable(true);
  EXPECT_CALL(provider, SelectCarrier(_)).WillOnce(Return(device_));
  EXPECT_CALL(*device_, IsIdle()).WillOnce(Return(false));
  reason = "";
  EXPECT_FALSE(service_->IsAutoConnectable(&reason));
  EXPECT_EQ(WiMaxService::kAutoConnBusy, reason);

  EXPECT_CALL(provider, SelectCarrier(_)).WillOnce(Return(device_));
  EXPECT_CALL(*device_, IsIdle()).WillOnce(Return(true));
  reason = "";
  EXPECT_TRUE(service_->IsAutoConnectable(&reason));
  EXPECT_STREQ("", reason);
}

TEST_F(WiMaxServiceTest, PropertyChanges) {
  ServiceMockAdaptor *adaptor = GetAdaptor();
  TestCommonPropertyChanges(service_, adaptor);
  TestAutoConnectPropertyChange(service_, adaptor);

  EXPECT_CALL(*adaptor,
              EmitRpcIdentifierChanged(kDeviceProperty, _));
  SetDevice(device_);
  Mock::VerifyAndClearExpectations(adaptor);

  EXPECT_CALL(*adaptor,
              EmitRpcIdentifierChanged(kDeviceProperty, _));
  SetDevice(NULL);
  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(WiMaxServiceTest, CustomSetterNoopChange) {
  TestCustomSetterNoopChange(service_, &manager_);
}

}  // namespace shill
