// 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/string_util.h>
#include <chromeos/dbus/service_constants.h>
#include <dbus/dbus-glib.h>
#include <glib.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 ((type == kNetCellular &&
            !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
