// 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 <set>
#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"));
  GPtrArray* array = NULL;
  bool success = false;
  if (G_VALUE_HOLDS(value, DBUS_TYPE_G_OBJECT_PATH_ARRAY) &&
      (array = reinterpret_cast<GPtrArray*>(g_value_get_boxed(value))) &&
      (array->len > 0)) {
    *out_path = static_cast<const char*>(g_ptr_array_index(array, 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 =
      reinterpret_cast<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 = reinterpret_cast<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 = reinterpret_cast<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
