//
// Copyright (C) 2014 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 "update_engine/update_manager/real_shill_provider.h"

#include <memory>
#include <utility>

#include <base/time/time.h>
#include <brillo/make_unique_ptr.h>
#include <brillo/message_loops/fake_message_loop.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <shill/dbus-constants.h>
#include <shill/dbus-proxies.h>
#include <shill/dbus-proxy-mocks.h>

#include "update_engine/common/fake_clock.h"
#include "update_engine/common/test_utils.h"
#include "update_engine/dbus_test_utils.h"
#include "update_engine/fake_shill_proxy.h"
#include "update_engine/update_manager/umtest_utils.h"

using base::Time;
using base::TimeDelta;
using chromeos_update_engine::FakeClock;
using org::chromium::flimflam::ManagerProxyMock;
using org::chromium::flimflam::ServiceProxyMock;
using std::unique_ptr;
using testing::Mock;
using testing::Return;
using testing::SetArgPointee;
using testing::_;

namespace {

// Fake service paths.
const char* const kFakeEthernetServicePath = "/fake/ethernet/service";
const char* const kFakeWifiServicePath = "/fake/wifi/service";
const char* const kFakeWimaxServicePath = "/fake/wimax/service";
const char* const kFakeBluetoothServicePath = "/fake/bluetooth/service";
const char* const kFakeCellularServicePath = "/fake/cellular/service";
const char* const kFakeVpnServicePath = "/fake/vpn/service";
const char* const kFakeUnknownServicePath = "/fake/unknown/service";

}  // namespace

namespace chromeos_update_manager {

class UmRealShillProviderTest : public ::testing::Test {
 protected:
  // Initialize the RealShillProvider under test.
  void SetUp() override {
    fake_clock_.SetWallclockTime(InitTime());
    loop_.SetAsCurrent();
    provider_.reset(new RealShillProvider(&fake_shill_proxy_, &fake_clock_));

    ManagerProxyMock* manager_proxy_mock = fake_shill_proxy_.GetManagerProxy();

    // The PropertyChanged signal should be subscribed to.
    MOCK_SIGNAL_HANDLER_EXPECT_SIGNAL_HANDLER(
        manager_property_changed_, *manager_proxy_mock, PropertyChanged);
  }

  void TearDown() override {
    provider_.reset();
    // Check for leaked callbacks on the main loop.
    EXPECT_FALSE(loop_.PendingTasks());
  }

  // These methods generate fixed timestamps for use in faking the current time.
  Time InitTime() {
    Time::Exploded now_exp;
    now_exp.year = 2014;
    now_exp.month = 3;
    now_exp.day_of_week = 2;
    now_exp.day_of_month = 18;
    now_exp.hour = 8;
    now_exp.minute = 5;
    now_exp.second = 33;
    now_exp.millisecond = 675;
    return Time::FromLocalExploded(now_exp);
  }

  Time ConnChangedTime() {
    return InitTime() + TimeDelta::FromSeconds(10);
  }

  // Sets the default_service object path in the response from the
  // ManagerProxyMock instance.
  void SetManagerReply(const char* default_service, bool reply_succeeds);

  // Sets the |service_type|, |physical_technology| and |service_tethering|
  // properties in the mocked service |service_path|. If any of the three
  // const char* is a nullptr, the corresponding property will not be included
  // in the response.
  // Returns the mock object pointer, owned by the |fake_shill_proxy_|.
  ServiceProxyMock* SetServiceReply(const std::string& service_path,
                                    const char* service_type,
                                    const char* physical_technology,
                                    const char* service_tethering);

  void InitWithDefaultService(const char* default_service) {
    SetManagerReply(default_service, true);
    // Check that provider initializes correctly.
    EXPECT_TRUE(provider_->Init());
    // RunOnce to notify the signal handler was connected properly.
    EXPECT_TRUE(loop_.RunOnce(false));
  }

  // Sends a signal informing the provider about a default connection
  // |service_path|. Sets the fake connection change time in
  // |conn_change_time_p| if provided.
  void SendDefaultServiceSignal(const std::string& service_path,
                                Time* conn_change_time_p) {
    const Time conn_change_time = ConnChangedTime();
    fake_clock_.SetWallclockTime(conn_change_time);
    ASSERT_TRUE(manager_property_changed_.IsHandlerRegistered());
    manager_property_changed_.signal_callback().Run(
        shill::kDefaultServiceProperty, dbus::ObjectPath(service_path));
    fake_clock_.SetWallclockTime(conn_change_time + TimeDelta::FromSeconds(5));
    if (conn_change_time_p)
      *conn_change_time_p = conn_change_time;
  }

  // Sets up expectations for detection of a connection |service_path| with type
  // |shill_type_str| and tethering mode |shill_tethering_str|. Ensures that the
  // new connection status and change time are properly detected by the
  // provider. Writes the fake connection change time to |conn_change_time_p|,
  // if provided.
  void SetupConnectionAndAttrs(const std::string& service_path,
                               const char* shill_type,
                               const char* shill_tethering,
                               Time* conn_change_time_p) {
    SetServiceReply(service_path, shill_type, nullptr, shill_tethering);
    // Note: We don't setup this |service_path| as the default service path but
    // we instead send a signal notifying the change since the code won't call
    // GetProperties on the Manager object at this point.

    // Send a signal about a new default service.
    Time conn_change_time;
    SendDefaultServiceSignal(service_path, &conn_change_time);

    // Query the connection status, ensure last change time reported correctly.
    UmTestUtils::ExpectVariableHasValue(true, provider_->var_is_connected());
    UmTestUtils::ExpectVariableHasValue(conn_change_time,
                                        provider_->var_conn_last_changed());

    // Write the connection change time to the output argument.
    if (conn_change_time_p)
      *conn_change_time_p = conn_change_time;
  }

  // Sets up a connection and tests that its type is being properly detected by
  // the provider.
  void SetupConnectionAndTestType(const char* service_path,
                                  const char* shill_type,
                                  ConnectionType expected_conn_type) {
    // Set up and test the connection, record the change time.
    Time conn_change_time;
    SetupConnectionAndAttrs(service_path,
                            shill_type,
                            shill::kTetheringNotDetectedState,
                            &conn_change_time);

    // Query the connection type, ensure last change time did not change.
    UmTestUtils::ExpectVariableHasValue(expected_conn_type,
                                        provider_->var_conn_type());
    UmTestUtils::ExpectVariableHasValue(conn_change_time,
                                        provider_->var_conn_last_changed());
  }

  // Sets up a connection and tests that its tethering mode is being properly
  // detected by the provider.
  void SetupConnectionAndTestTethering(
      const char* service_path,
      const char* shill_tethering,
      ConnectionTethering expected_conn_tethering) {
    // Set up and test the connection, record the change time.
    Time conn_change_time;
    SetupConnectionAndAttrs(
        service_path, shill::kTypeEthernet, shill_tethering, &conn_change_time);

    // Query the connection tethering, ensure last change time did not change.
    UmTestUtils::ExpectVariableHasValue(expected_conn_tethering,
                                        provider_->var_conn_tethering());
    UmTestUtils::ExpectVariableHasValue(conn_change_time,
                                        provider_->var_conn_last_changed());
  }

  brillo::FakeMessageLoop loop_{nullptr};
  FakeClock fake_clock_;
  chromeos_update_engine::FakeShillProxy fake_shill_proxy_;

  // The registered signal handler for the signal Manager.PropertyChanged.
  chromeos_update_engine::dbus_test_utils::MockSignalHandler<
      void(const std::string&, const brillo::Any&)> manager_property_changed_;

  unique_ptr<RealShillProvider> provider_;
};

void UmRealShillProviderTest::SetManagerReply(const char* default_service,
                                              bool reply_succeeds) {
  ManagerProxyMock* manager_proxy_mock = fake_shill_proxy_.GetManagerProxy();
  if (!reply_succeeds) {
    EXPECT_CALL(*manager_proxy_mock, GetProperties(_, _, _))
        .WillOnce(Return(false));
    return;
  }

  // Create a dictionary of properties and optionally include the default
  // service.
  brillo::VariantDictionary reply_dict;
  reply_dict["SomeOtherProperty"] = 0xC0FFEE;

  if (default_service) {
    reply_dict[shill::kDefaultServiceProperty] =
        dbus::ObjectPath(default_service);
  }
  EXPECT_CALL(*manager_proxy_mock, GetProperties(_, _, _))
      .WillOnce(DoAll(SetArgPointee<0>(reply_dict), Return(true)));
}

ServiceProxyMock* UmRealShillProviderTest::SetServiceReply(
    const std::string& service_path,
    const char* service_type,
    const char* physical_technology,
    const char* service_tethering) {
  brillo::VariantDictionary reply_dict;
  reply_dict["SomeOtherProperty"] = 0xC0FFEE;

  if (service_type)
    reply_dict[shill::kTypeProperty] = std::string(service_type);

  if (physical_technology) {
    reply_dict[shill::kPhysicalTechnologyProperty] =
        std::string(physical_technology);
  }

  if (service_tethering)
    reply_dict[shill::kTetheringProperty] = std::string(service_tethering);

  ServiceProxyMock* service_proxy_mock = new ServiceProxyMock();

  // Plumb return value into mock object.
  EXPECT_CALL(*service_proxy_mock, GetProperties(_, _, _))
      .WillOnce(DoAll(SetArgPointee<0>(reply_dict), Return(true)));

  fake_shill_proxy_.SetServiceForPath(
      dbus::ObjectPath(service_path),
      brillo::make_unique_ptr(service_proxy_mock));
  return service_proxy_mock;
}


// Query the connection status, type and time last changed, as they were set
// during initialization (no signals).
TEST_F(UmRealShillProviderTest, ReadBaseValues) {
  InitWithDefaultService("/");
  // Query the provider variables.
  UmTestUtils::ExpectVariableHasValue(false, provider_->var_is_connected());
  UmTestUtils::ExpectVariableNotSet(provider_->var_conn_type());
  UmTestUtils::ExpectVariableHasValue(InitTime(),
                                      provider_->var_conn_last_changed());
}

// Ensure that invalid DBus paths are ignored.
TEST_F(UmRealShillProviderTest, InvalidServicePath) {
  InitWithDefaultService("invalid");
  UmTestUtils::ExpectVariableHasValue(false, provider_->var_is_connected());
  UmTestUtils::ExpectVariableNotSet(provider_->var_conn_type());
  UmTestUtils::ExpectVariableHasValue(InitTime(),
                                      provider_->var_conn_last_changed());
}

// Ensure that a service path property including a different type is ignored.
TEST_F(UmRealShillProviderTest, InvalidServicePathType) {
  ManagerProxyMock* manager_proxy_mock = fake_shill_proxy_.GetManagerProxy();
  brillo::VariantDictionary reply_dict;
  reply_dict[shill::kDefaultServiceProperty] = "/not/an/object/path";
  EXPECT_CALL(*manager_proxy_mock, GetProperties(_, _, _))
      .WillOnce(DoAll(SetArgPointee<0>(reply_dict), Return(true)));

  EXPECT_TRUE(provider_->Init());
  EXPECT_TRUE(loop_.RunOnce(false));

  UmTestUtils::ExpectVariableHasValue(false, provider_->var_is_connected());
}

// Test that Ethernet connection is identified correctly.
TEST_F(UmRealShillProviderTest, ReadConnTypeEthernet) {
  InitWithDefaultService("/");
  SetupConnectionAndTestType(kFakeEthernetServicePath,
                             shill::kTypeEthernet,
                             ConnectionType::kEthernet);
}

// Test that Wifi connection is identified correctly.
TEST_F(UmRealShillProviderTest, ReadConnTypeWifi) {
  InitWithDefaultService("/");
  SetupConnectionAndTestType(kFakeWifiServicePath,
                             shill::kTypeWifi,
                             ConnectionType::kWifi);
}

// Test that Wimax connection is identified correctly.
TEST_F(UmRealShillProviderTest, ReadConnTypeWimax) {
  InitWithDefaultService("/");
  SetupConnectionAndTestType(kFakeWimaxServicePath,
                             shill::kTypeWimax,
                             ConnectionType::kWimax);
}

// Test that Bluetooth connection is identified correctly.
TEST_F(UmRealShillProviderTest, ReadConnTypeBluetooth) {
  InitWithDefaultService("/");
  SetupConnectionAndTestType(kFakeBluetoothServicePath,
                             shill::kTypeBluetooth,
                             ConnectionType::kBluetooth);
}

// Test that Cellular connection is identified correctly.
TEST_F(UmRealShillProviderTest, ReadConnTypeCellular) {
  InitWithDefaultService("/");
  SetupConnectionAndTestType(kFakeCellularServicePath,
                             shill::kTypeCellular,
                             ConnectionType::kCellular);
}

// Test that an unknown connection is identified as such.
TEST_F(UmRealShillProviderTest, ReadConnTypeUnknown) {
  InitWithDefaultService("/");
  SetupConnectionAndTestType(kFakeUnknownServicePath,
                             "FooConnectionType",
                             ConnectionType::kUnknown);
}

// Tests that VPN connection is identified correctly.
TEST_F(UmRealShillProviderTest, ReadConnTypeVpn) {
  InitWithDefaultService("/");
  // Mock logic for returning a default service path and its type.
  SetServiceReply(kFakeVpnServicePath,
                  shill::kTypeVPN,
                  shill::kTypeWifi,
                  shill::kTetheringNotDetectedState);

  // Send a signal about a new default service.
  Time conn_change_time;
  SendDefaultServiceSignal(kFakeVpnServicePath, &conn_change_time);

  // Query the connection type, ensure last change time reported correctly.
  UmTestUtils::ExpectVariableHasValue(ConnectionType::kWifi,
                                      provider_->var_conn_type());
  UmTestUtils::ExpectVariableHasValue(conn_change_time,
                                      provider_->var_conn_last_changed());
}

// Ensure that the connection type is properly cached in the provider through
// subsequent variable readings.
TEST_F(UmRealShillProviderTest, ConnTypeCacheUsed) {
  InitWithDefaultService("/");
  SetupConnectionAndTestType(kFakeEthernetServicePath,
                             shill::kTypeEthernet,
                             ConnectionType::kEthernet);

  UmTestUtils::ExpectVariableHasValue(ConnectionType::kEthernet,
                                      provider_->var_conn_type());
}

// Ensure that the cached connection type remains valid even when a default
// connection signal occurs but the connection is not changed.
TEST_F(UmRealShillProviderTest, ConnTypeCacheRemainsValid) {
  InitWithDefaultService("/");
  SetupConnectionAndTestType(kFakeEthernetServicePath,
                             shill::kTypeEthernet,
                             ConnectionType::kEthernet);

  SendDefaultServiceSignal(kFakeEthernetServicePath, nullptr);

  UmTestUtils::ExpectVariableHasValue(ConnectionType::kEthernet,
                                      provider_->var_conn_type());
}

// Ensure that the cached connection type is invalidated and re-read when the
// default connection changes.
TEST_F(UmRealShillProviderTest, ConnTypeCacheInvalidated) {
  InitWithDefaultService("/");
  SetupConnectionAndTestType(kFakeEthernetServicePath,
                             shill::kTypeEthernet,
                             ConnectionType::kEthernet);

  SetupConnectionAndTestType(kFakeWifiServicePath,
                             shill::kTypeWifi,
                             ConnectionType::kWifi);
}

// Test that a non-tethering mode is identified correctly.
TEST_F(UmRealShillProviderTest, ReadConnTetheringNotDetected) {
  InitWithDefaultService("/");
  SetupConnectionAndTestTethering(kFakeWifiServicePath,
                                  shill::kTetheringNotDetectedState,
                                  ConnectionTethering::kNotDetected);
}

// Test that a suspected tethering mode is identified correctly.
TEST_F(UmRealShillProviderTest, ReadConnTetheringSuspected) {
  InitWithDefaultService("/");
  SetupConnectionAndTestTethering(kFakeWifiServicePath,
                                  shill::kTetheringSuspectedState,
                                  ConnectionTethering::kSuspected);
}

// Test that a confirmed tethering mode is identified correctly.
TEST_F(UmRealShillProviderTest, ReadConnTetheringConfirmed) {
  InitWithDefaultService("/");
  SetupConnectionAndTestTethering(kFakeWifiServicePath,
                                  shill::kTetheringConfirmedState,
                                  ConnectionTethering::kConfirmed);
}

// Test that an unknown tethering mode is identified as such.
TEST_F(UmRealShillProviderTest, ReadConnTetheringUnknown) {
  InitWithDefaultService("/");
  SetupConnectionAndTestTethering(kFakeWifiServicePath,
                                  "FooConnTethering",
                                  ConnectionTethering::kUnknown);
}

// Ensure that the connection tethering mode is properly cached in the provider.
TEST_F(UmRealShillProviderTest, ConnTetheringCacheUsed) {
  InitWithDefaultService("/");
  SetupConnectionAndTestTethering(kFakeEthernetServicePath,
                                  shill::kTetheringNotDetectedState,
                                  ConnectionTethering::kNotDetected);

  UmTestUtils::ExpectVariableHasValue(ConnectionTethering::kNotDetected,
                                      provider_->var_conn_tethering());
}

// Ensure that the cached connection tethering mode remains valid even when a
// default connection signal occurs but the connection is not changed.
TEST_F(UmRealShillProviderTest, ConnTetheringCacheRemainsValid) {
  InitWithDefaultService("/");
  SetupConnectionAndTestTethering(kFakeEthernetServicePath,
                                  shill::kTetheringNotDetectedState,
                                  ConnectionTethering::kNotDetected);

  SendDefaultServiceSignal(kFakeEthernetServicePath, nullptr);

  UmTestUtils::ExpectVariableHasValue(ConnectionTethering::kNotDetected,
                                      provider_->var_conn_tethering());
}

// Ensure that the cached connection tethering mode is invalidated and re-read
// when the default connection changes.
TEST_F(UmRealShillProviderTest, ConnTetheringCacheInvalidated) {
  InitWithDefaultService("/");
  SetupConnectionAndTestTethering(kFakeEthernetServicePath,
                                  shill::kTetheringNotDetectedState,
                                  ConnectionTethering::kNotDetected);

  SetupConnectionAndTestTethering(kFakeWifiServicePath,
                                  shill::kTetheringConfirmedState,
                                  ConnectionTethering::kConfirmed);
}

// Fake two DBus signals prompting a default connection change, but otherwise
// give the same service path. Check connection status and the time it was last
// changed, making sure that it is the time when the first signal was sent (and
// not the second).
TEST_F(UmRealShillProviderTest, ReadLastChangedTimeTwoSignals) {
  InitWithDefaultService("/");
  // Send a default service signal twice, advancing the clock in between.
  Time conn_change_time;
  SetupConnectionAndAttrs(kFakeEthernetServicePath,
                          shill::kTypeEthernet,
                          shill::kTetheringNotDetectedState,
                          &conn_change_time);
  // This will set the service path to the same value, so it should not call
  // GetProperties() again.
  SendDefaultServiceSignal(kFakeEthernetServicePath, nullptr);

  // Query the connection status, ensure last change time reported as the first
  // time the signal was sent.
  UmTestUtils::ExpectVariableHasValue(true, provider_->var_is_connected());
  UmTestUtils::ExpectVariableHasValue(conn_change_time,
                                      provider_->var_conn_last_changed());
}

// Make sure that the provider initializes correctly even if shill is not
// responding, that variables can be obtained, and that they all return a null
// value (indicating that the underlying values were not set).
TEST_F(UmRealShillProviderTest, NoInitConnStatusReadBaseValues) {
  // Initialize the provider, no initial connection status response.
  SetManagerReply(nullptr, false);
  EXPECT_TRUE(provider_->Init());
  EXPECT_TRUE(loop_.RunOnce(false));
  UmTestUtils::ExpectVariableNotSet(provider_->var_is_connected());
  UmTestUtils::ExpectVariableNotSet(provider_->var_conn_type());
  UmTestUtils::ExpectVariableNotSet(provider_->var_conn_last_changed());
}

// Test that, once a signal is received, the connection status and other info
// can be read correctly.
TEST_F(UmRealShillProviderTest, NoInitConnStatusReadConnTypeEthernet) {
  // Initialize the provider with no initial connection status response.
  SetManagerReply(nullptr, false);
  EXPECT_TRUE(provider_->Init());
  EXPECT_TRUE(loop_.RunOnce(false));

  SetupConnectionAndAttrs(kFakeEthernetServicePath,
                          shill::kTypeEthernet,
                          shill::kTetheringNotDetectedState,
                          nullptr);
  UmTestUtils::ExpectVariableHasValue(true, provider_->var_is_connected());
}

}  // namespace chromeos_update_manager
