// 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 "update_engine/connection_manager.h"

#include <string>

#include <base/stl_util.h>
#include <base/strings/string_util.h>
#include <chromeos/dbus/service_constants.h>
#include <dbus/dbus-glib.h>
#include <glib.h>
#include <policy/device_policy.h>

#include "update_engine/prefs.h"
#include "update_engine/system_state.h"
#include "update_engine/utils.h"

using std::set;
using std::string;

namespace chromeos_update_engine {

namespace {

// Gets the DbusGProxy for FlimFlam. Must be free'd with ProxyUnref()
bool GetFlimFlamProxy(DBusWrapperInterface* dbus_iface,
                      const char* path,
                      const char* interface,
                      DBusGProxy** out_proxy) {
  DBusGConnection* bus;
  DBusGProxy* proxy;
  GError* error = NULL;

  bus = dbus_iface->BusGet(DBUS_BUS_SYSTEM, &error);
  if (!bus) {
    LOG(ERROR) << "Failed to get system bus";
    return false;
  }
  proxy = dbus_iface->ProxyNewForName(bus, shill::kFlimflamServiceName, path,
                                      interface);
  *out_proxy = proxy;
  return true;
}

// On success, caller owns the GHashTable at out_hash_table.
// Returns true on success.
bool GetProperties(DBusWrapperInterface* dbus_iface,
                   const char* path,
                   const char* interface,
                   GHashTable** out_hash_table) {
  DBusGProxy* proxy;
  GError* error = NULL;

  TEST_AND_RETURN_FALSE(GetFlimFlamProxy(dbus_iface,
                                         path,
                                         interface,
                                         &proxy));

  gboolean rc = dbus_iface->ProxyCall_0_1(proxy,
                                          "GetProperties",
                                          &error,
                                          out_hash_table);
  dbus_iface->ProxyUnref(proxy);
  if (rc == FALSE) {
    LOG(ERROR) << "dbus_g_proxy_call failed";
    return false;
  }

  return true;
}

// Returns (via out_path) the default network path, or empty string if
// there's no network up.
// Returns true on success.
bool GetDefaultServicePath(DBusWrapperInterface* dbus_iface, string* out_path) {
  GHashTable* hash_table = NULL;

  TEST_AND_RETURN_FALSE(GetProperties(dbus_iface,
                                      shill::kFlimflamServicePath,
                                      shill::kFlimflamManagerInterface,
                                      &hash_table));

  GValue* value = reinterpret_cast<GValue*>(g_hash_table_lookup(hash_table,
                                                                "Services"));
  GArray* array = NULL;
  bool success = false;
  if (G_VALUE_HOLDS(value, DBUS_TYPE_G_OBJECT_PATH_ARRAY) &&
      (array = reinterpret_cast<GArray*>(g_value_get_boxed(value))) &&
      (array->len > 0)) {
    *out_path = g_array_index(array, const char*, 0);
    success = true;
  }

  g_hash_table_unref(hash_table);
  return success;
}

NetworkConnectionType ParseConnectionType(const char* type_str) {
  if (!strcmp(type_str, shill::kTypeEthernet)) {
    return kNetEthernet;
  } else if (!strcmp(type_str, shill::kTypeWifi)) {
    return kNetWifi;
  } else if (!strcmp(type_str, shill::kTypeWimax)) {
    return kNetWimax;
  } else if (!strcmp(type_str, shill::kTypeBluetooth)) {
    return kNetBluetooth;
  } else if (!strcmp(type_str, shill::kTypeCellular)) {
    return kNetCellular;
  }
  return kNetUnknown;
}

NetworkTethering ParseTethering(const char* tethering_str) {
  if (!strcmp(tethering_str, shill::kTetheringNotDetectedState)) {
    return NetworkTethering::kNotDetected;
  } else if (!strcmp(tethering_str, shill::kTetheringSuspectedState)) {
    return NetworkTethering::kSuspected;
  } else if (!strcmp(tethering_str, shill::kTetheringConfirmedState)) {
    return NetworkTethering::kConfirmed;
  }
  LOG(WARNING) << "Unknown Tethering value: " << tethering_str;
  return NetworkTethering::kUnknown;
}

bool GetServicePathProperties(DBusWrapperInterface* dbus_iface,
                              const string& path,
                              NetworkConnectionType* out_type,
                              NetworkTethering* out_tethering) {
  GHashTable* hash_table = NULL;

  TEST_AND_RETURN_FALSE(GetProperties(dbus_iface,
                                      path.c_str(),
                                      shill::kFlimflamServiceInterface,
                                      &hash_table));

  // Populate the out_tethering.
  GValue* value = (GValue*)g_hash_table_lookup(hash_table,
                                               shill::kTetheringProperty);
  const char* tethering_str = NULL;

  if (value != NULL)
    tethering_str = g_value_get_string(value);
  if (tethering_str != NULL) {
    *out_tethering = ParseTethering(tethering_str);
  } else {
    // Set to Unknown if not present.
    *out_tethering = NetworkTethering::kUnknown;
  }

  // Populate the out_type property.
  value = (GValue*)g_hash_table_lookup(hash_table,
                                       shill::kTypeProperty);
  const char* type_str = NULL;
  bool success = false;
  if (value != NULL && (type_str = g_value_get_string(value)) != NULL) {
    success = true;
    if (!strcmp(type_str, shill::kTypeVPN)) {
      value = (GValue*)g_hash_table_lookup(hash_table,
                                           shill::kPhysicalTechnologyProperty);
      if (value != NULL && (type_str = g_value_get_string(value)) != NULL) {
        *out_type = ParseConnectionType(type_str);
      } else {
        LOG(ERROR) << "No PhysicalTechnology property found for a VPN"
                   << " connection (service: " << path << "). Returning default"
                   << " kNetUnknown value.";
        *out_type = kNetUnknown;
      }
    } else {
      *out_type = ParseConnectionType(type_str);
    }
  }
  g_hash_table_unref(hash_table);
  return success;
}

}  // namespace {}

ConnectionManager::ConnectionManager(SystemState *system_state)
    :  system_state_(system_state) {}

bool ConnectionManager::IsUpdateAllowedOver(NetworkConnectionType type,
                                            NetworkTethering tethering) const {
  switch (type) {
    case kNetBluetooth:
      return false;

    case kNetCellular: {
      set<string> allowed_types;
      const policy::DevicePolicy* device_policy =
          system_state_->device_policy();

      // A device_policy is loaded in a lazy way right before an update check,
      // so the device_policy should be already loaded at this point. If it's
      // not, return a safe value for this setting.
      if (!device_policy) {
        LOG(INFO) << "Disabling updates over cellular networks as there's no "
                     "device policy loaded yet.";
        return false;
      }

      if (device_policy->GetAllowedConnectionTypesForUpdate(&allowed_types)) {
        // The update setting is enforced by the device policy.

        if (!ContainsKey(allowed_types, shill::kTypeCellular)) {
          LOG(INFO) << "Disabling updates over cellular connection as it's not "
                       "allowed in the device policy.";
          return false;
        }

        LOG(INFO) << "Allowing updates over cellular per device policy.";
        return true;
      } else {
        // There's no update setting in the device policy, using the local user
        // setting.
        PrefsInterface* prefs = system_state_->prefs();

        if (!prefs || !prefs->Exists(kPrefsUpdateOverCellularPermission)) {
          LOG(INFO) << "Disabling updates over cellular connection as there's "
                       "no device policy setting nor user preference present.";
          return false;
        }

        bool stored_value;
        if (!prefs->GetBoolean(kPrefsUpdateOverCellularPermission,
                               &stored_value)) {
          return false;
        }

        if (!stored_value) {
          LOG(INFO) << "Disabling updates over cellular connection per user "
                       "setting.";
          return false;
        }
        LOG(INFO) << "Allowing updates over cellular per user setting.";
        return true;
      }
    }

    default:
      if (tethering == NetworkTethering::kConfirmed) {
        // Treat this connection as if it is a cellular connection.
        LOG(INFO) << "Current connection is confirmed tethered, using Cellular "
                     "setting.";
        return IsUpdateAllowedOver(kNetCellular, NetworkTethering::kUnknown);
      }
      return true;
  }
}

const char* ConnectionManager::StringForConnectionType(
    NetworkConnectionType type) const {
  static const char* const kValues[] = {shill::kTypeEthernet,
                                        shill::kTypeWifi,
                                        shill::kTypeWimax,
                                        shill::kTypeBluetooth,
                                        shill::kTypeCellular};
  if (type < 0 || type >= static_cast<int>(arraysize(kValues))) {
    return "Unknown";
  }
  return kValues[type];
}

const char* ConnectionManager::StringForTethering(
    NetworkTethering tethering) const {
  switch (tethering) {
    case NetworkTethering::kNotDetected:
      return shill::kTetheringNotDetectedState;
    case NetworkTethering::kSuspected:
      return shill::kTetheringSuspectedState;
    case NetworkTethering::kConfirmed:
      return shill::kTetheringConfirmedState;
    case NetworkTethering::kUnknown:
      return "Unknown";
  }
  // The program shouldn't reach this point, but the compiler isn't smart
  // enough to infer that.
  return "Unknown";
}

bool ConnectionManager::GetConnectionProperties(
    DBusWrapperInterface* dbus_iface,
    NetworkConnectionType* out_type,
    NetworkTethering* out_tethering) const {
  string default_service_path;
  TEST_AND_RETURN_FALSE(GetDefaultServicePath(dbus_iface,
                                              &default_service_path));
  TEST_AND_RETURN_FALSE(GetServicePathProperties(dbus_iface,
                                                 default_service_path,
                                                 out_type, out_tethering));
  return true;
}

}  // namespace chromeos_update_engine
