// Copyright (c) 2012 The Chromium 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 <string>
#include <utility>

#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/strings/string_util.h"
#include "base/values.h"
#include "chromeos/network/network_profile_handler.h"
#include "chromeos/network/network_state.h"
#include "chromeos/network/network_util.h"
#include "chromeos/network/onc/onc_signature.h"
#include "chromeos/network/onc/onc_translation_tables.h"
#include "chromeos/network/onc/onc_translator.h"
#include "chromeos/network/onc/onc_utils.h"
#include "chromeos/network/shill_property_util.h"
#include "components/onc/onc_constants.h"
#include "third_party/cros_system_api/dbus/service_constants.h"

namespace chromeos {
namespace onc {

namespace {

// Converts |str| to a base::Value of the given |type|. If the conversion fails,
// returns NULL.
std::unique_ptr<base::Value> ConvertStringToValue(const std::string& str,
                                                  base::Value::Type type) {
  std::unique_ptr<base::Value> value;
  if (type == base::Value::Type::STRING) {
    value.reset(new base::Value(str));
  } else {
    value = base::JSONReader::Read(str);
  }
  if (value && value->GetType() != type)
    return nullptr;

  return value;
}

// This class implements the translation of properties from the given
// |shill_dictionary| to a new ONC object of signature |onc_signature|. Using
// recursive calls to CreateTranslatedONCObject of new instances, nested objects
// are translated.
class ShillToONCTranslator {
 public:
  ShillToONCTranslator(const base::DictionaryValue& shill_dictionary,
                       ::onc::ONCSource onc_source,
                       const OncValueSignature& onc_signature,
                       const NetworkState* network_state)
      : shill_dictionary_(&shill_dictionary),
        onc_source_(onc_source),
        onc_signature_(&onc_signature),
        network_state_(network_state) {
    field_translation_table_ = GetFieldTranslationTable(onc_signature);
  }

  ShillToONCTranslator(const base::DictionaryValue& shill_dictionary,
                       ::onc::ONCSource onc_source,
                       const OncValueSignature& onc_signature,
                       const FieldTranslationEntry* field_translation_table,
                       const NetworkState* network_state)
      : shill_dictionary_(&shill_dictionary),
        onc_source_(onc_source),
        onc_signature_(&onc_signature),
        field_translation_table_(field_translation_table),
        network_state_(network_state) {}

  // Translates the associated Shill dictionary and creates an ONC object of the
  // given signature.
  std::unique_ptr<base::DictionaryValue> CreateTranslatedONCObject();

 private:
  void TranslateEthernet();
  void TranslateOpenVPN();
  void TranslateIPsec();
  void TranslateThirdPartyVPN();
  void TranslateVPN();
  void TranslateWiFiWithState();
  void TranslateWiMAXWithState();
  void TranslateCellularWithState();
  void TranslateCellularDevice();
  void TranslateNetworkWithState();
  void TranslateIPConfig();
  void TranslateSavedOrStaticIPConfig();
  void TranslateSavedIPConfig();
  void TranslateStaticIPConfig();
  void TranslateEap();

  // Creates an ONC object from |dictionary| according to the signature
  // associated to |onc_field_name| and adds it to |onc_object_| at
  // |onc_field_name|.
  void TranslateAndAddNestedObject(const std::string& onc_field_name,
                                   const base::DictionaryValue& dictionary);

  // Creates an ONC object from |shill_dictionary_| according to the signature
  // associated to |onc_field_name| and adds it to |onc_object_| at
  // |onc_field_name|.
  void TranslateAndAddNestedObject(const std::string& onc_field_name);

  // Sets |onc_field_name| in dictionary |onc_dictionary_name| in |onc_object_|
  // to |value| if the dictionary exists.
  void SetNestedOncValue(const std::string& onc_dictionary_name,
                         const std::string& onc_field_name,
                         const base::Value& value);

  // Translates a list of nested objects and adds the list to |onc_object_| at
  // |onc_field_name|. If there are errors while parsing individual objects or
  // if the resulting list contains no entries, the result will not be added to
  // |onc_object_|.
  void TranslateAndAddListOfObjects(const std::string& onc_field_name,
                                    const base::ListValue& list);

  // Applies function CopyProperty to each field of |value_signature| and its
  // base signatures.
  void CopyPropertiesAccordingToSignature(
      const OncValueSignature* value_signature);

  // Applies function CopyProperty to each field of |onc_signature_| and its
  // base signatures.
  void CopyPropertiesAccordingToSignature();

  // If |shill_property_name| is defined in |field_signature|, copies this
  // entry from |shill_dictionary_| to |onc_object_| if it exists.
  void CopyProperty(const OncFieldSignature* field_signature);

  // If existent, translates the entry at |shill_property_name| in
  // |shill_dictionary_| using |table|. It is an error if no matching table
  // entry is found. Writes the result as entry at |onc_field_name| in
  // |onc_object_|.
  void TranslateWithTableAndSet(const std::string& shill_property_name,
                                const StringTranslationEntry table[],
                                const std::string& onc_field_name);

  // Returns the name of the Shill service provided in |shill_dictionary_|
  // for debugging.
  std::string GetName();

  const base::DictionaryValue* shill_dictionary_;
  ::onc::ONCSource onc_source_;
  const OncValueSignature* onc_signature_;
  const FieldTranslationEntry* field_translation_table_;
  std::unique_ptr<base::DictionaryValue> onc_object_;
  const NetworkState* network_state_;

  DISALLOW_COPY_AND_ASSIGN(ShillToONCTranslator);
};

std::unique_ptr<base::DictionaryValue>
ShillToONCTranslator::CreateTranslatedONCObject() {
  onc_object_.reset(new base::DictionaryValue);
  if (onc_signature_ == &kNetworkWithStateSignature) {
    TranslateNetworkWithState();
  } else if (onc_signature_ == &kEthernetSignature) {
    TranslateEthernet();
  } else if (onc_signature_ == &kVPNSignature) {
    TranslateVPN();
  } else if (onc_signature_ == &kOpenVPNSignature) {
    TranslateOpenVPN();
  } else if (onc_signature_ == &kIPsecSignature) {
    TranslateIPsec();
  } else if (onc_signature_ == &kThirdPartyVPNSignature) {
    TranslateThirdPartyVPN();
  } else if (onc_signature_ == &kWiFiWithStateSignature) {
    TranslateWiFiWithState();
  } else if (onc_signature_ == &kWiMAXWithStateSignature) {
    TranslateWiMAXWithState();
  } else if (onc_signature_ == &kCellularWithStateSignature) {
    if (field_translation_table_ == kCellularDeviceTable)
      TranslateCellularDevice();
    else
      TranslateCellularWithState();
  } else if (onc_signature_ == &kIPConfigSignature) {
    TranslateIPConfig();
  } else if (onc_signature_ == &kSavedIPConfigSignature) {
    TranslateSavedIPConfig();
  } else if (onc_signature_ == &kStaticIPConfigSignature) {
    TranslateStaticIPConfig();
  } else if (onc_signature_ == &kEAPSignature) {
    TranslateEap();
  } else {
    CopyPropertiesAccordingToSignature();
  }
  return std::move(onc_object_);
}

void ShillToONCTranslator::TranslateEthernet() {
  std::string shill_network_type;
  shill_dictionary_->GetStringWithoutPathExpansion(shill::kTypeProperty,
                                                   &shill_network_type);
  const char* onc_auth = ::onc::ethernet::kAuthenticationNone;
  if (shill_network_type == shill::kTypeEthernetEap)
    onc_auth = ::onc::ethernet::k8021X;
  onc_object_->SetStringWithoutPathExpansion(::onc::ethernet::kAuthentication,
                                             onc_auth);
}

void ShillToONCTranslator::TranslateOpenVPN() {
  if (shill_dictionary_->HasKey(shill::kOpenVPNVerifyX509NameProperty))
    TranslateAndAddNestedObject(::onc::openvpn::kVerifyX509);

  // Shill supports only one RemoteCertKU but ONC requires a list. If existing,
  // wraps the value into a list.
  std::string certKU;
  if (shill_dictionary_->GetStringWithoutPathExpansion(
          shill::kOpenVPNRemoteCertKUProperty, &certKU)) {
    std::unique_ptr<base::ListValue> certKUs(new base::ListValue);
    certKUs->AppendString(certKU);
    onc_object_->SetWithoutPathExpansion(::onc::openvpn::kRemoteCertKU,
                                         std::move(certKUs));
  }

  for (const OncFieldSignature* field_signature = onc_signature_->fields;
       field_signature->onc_field_name != NULL; ++field_signature) {
    const std::string& onc_field_name = field_signature->onc_field_name;
    if (onc_field_name == ::onc::openvpn::kRemoteCertKU ||
        onc_field_name == ::onc::openvpn::kServerCAPEMs) {
      CopyProperty(field_signature);
      continue;
    }

    std::string shill_property_name;
    const base::Value* shill_value = NULL;
    if (!field_translation_table_ ||
        !GetShillPropertyName(field_signature->onc_field_name,
                              field_translation_table_, &shill_property_name) ||
        !shill_dictionary_->GetWithoutPathExpansion(shill_property_name,
                                                    &shill_value)) {
      continue;
    }

    std::unique_ptr<base::Value> translated;
    std::string shill_str;
    if (shill_value->GetAsString(&shill_str)) {
      // Shill wants all Provider/VPN fields to be strings. Translates these
      // strings back to the correct ONC type.
      translated = ConvertStringToValue(
          shill_str, field_signature->value_signature->onc_type);

      if (translated.get() == NULL) {
        LOG(ERROR) << "Shill property '" << shill_property_name
                   << "' with value " << *shill_value
                   << " couldn't be converted to base::Value::Type "
                   << field_signature->value_signature->onc_type << ": "
                   << GetName();
      } else {
        onc_object_->SetWithoutPathExpansion(onc_field_name,
                                             std::move(translated));
      }
    } else {
      LOG(ERROR) << "Shill property '" << shill_property_name << "' has value "
                 << *shill_value << ", but expected a string: " << GetName();
    }
  }
}

void ShillToONCTranslator::TranslateIPsec() {
  CopyPropertiesAccordingToSignature();
  if (shill_dictionary_->HasKey(shill::kL2tpIpsecXauthUserProperty))
    TranslateAndAddNestedObject(::onc::ipsec::kXAUTH);
  std::string client_cert_id;
  shill_dictionary_->GetStringWithoutPathExpansion(
      shill::kL2tpIpsecClientCertIdProperty, &client_cert_id);
  std::string authentication_type =
      client_cert_id.empty() ? ::onc::ipsec::kPSK : ::onc::ipsec::kCert;
  onc_object_->SetStringWithoutPathExpansion(::onc::ipsec::kAuthenticationType,
                                             authentication_type);
}

void ShillToONCTranslator::TranslateThirdPartyVPN() {
  CopyPropertiesAccordingToSignature();

  // For third-party VPNs, |shill::kProviderHostProperty| is used to store the
  // provider's extension ID.
  std::string shill_extension_id;
  shill_dictionary_->GetStringWithoutPathExpansion(shill::kHostProperty,
                                                   &shill_extension_id);
  onc_object_->SetStringWithoutPathExpansion(
      ::onc::third_party_vpn::kExtensionID, shill_extension_id);
}

void ShillToONCTranslator::TranslateVPN() {
  CopyPropertiesAccordingToSignature();

  // Parse Shill Provider dictionary. Note, this may not exist, e.g. if we are
  // just translating network state in network_util::TranslateNetworkStateToONC.
  const base::DictionaryValue* provider = NULL;
  if (!shill_dictionary_->GetDictionaryWithoutPathExpansion(
          shill::kProviderProperty, &provider)) {
    return;
  }
  std::string shill_provider_type, onc_provider_type;
  provider->GetStringWithoutPathExpansion(shill::kTypeProperty,
                                          &shill_provider_type);
  if (!TranslateStringToONC(kVPNTypeTable, shill_provider_type,
                            &onc_provider_type)) {
    return;
  }
  onc_object_->SetStringWithoutPathExpansion(::onc::vpn::kType,
                                             onc_provider_type);
  std::string shill_provider_host;
  if (onc_provider_type != ::onc::vpn::kThirdPartyVpn &&
      provider->GetStringWithoutPathExpansion(shill::kHostProperty,
                                              &shill_provider_host)) {
    onc_object_->SetStringWithoutPathExpansion(::onc::vpn::kHost,
                                               shill_provider_host);
  }

  // Translate the nested dictionary.
  std::string provider_type_dictionary;
  if (onc_provider_type == ::onc::vpn::kTypeL2TP_IPsec) {
    TranslateAndAddNestedObject(::onc::vpn::kIPsec, *provider);
    TranslateAndAddNestedObject(::onc::vpn::kL2TP, *provider);
    provider_type_dictionary = ::onc::vpn::kIPsec;
  } else {
    TranslateAndAddNestedObject(onc_provider_type, *provider);
    provider_type_dictionary = onc_provider_type;
  }

  bool save_credentials;
  if (onc_provider_type != ::onc::vpn::kThirdPartyVpn &&
      shill_dictionary_->GetBooleanWithoutPathExpansion(
          shill::kSaveCredentialsProperty, &save_credentials)) {
    SetNestedOncValue(provider_type_dictionary, ::onc::vpn::kSaveCredentials,
                      base::Value(save_credentials));
  }
}

void ShillToONCTranslator::TranslateWiFiWithState() {
  std::string shill_security;
  std::string shill_key_mgmt;
  if (shill_dictionary_->GetStringWithoutPathExpansion(
          shill::kSecurityClassProperty, &shill_security) &&
      shill_security == shill::kSecurityWep &&
      shill_dictionary_->GetStringWithoutPathExpansion(
          shill::kEapKeyMgmtProperty, &shill_key_mgmt) &&
      shill_key_mgmt == shill::kKeyManagementIEEE8021X) {
    onc_object_->SetStringWithoutPathExpansion(::onc::wifi::kSecurity,
                                               ::onc::wifi::kWEP_8021X);
  } else {
    TranslateWithTableAndSet(shill::kSecurityClassProperty, kWiFiSecurityTable,
                             ::onc::wifi::kSecurity);
  }

  bool unknown_encoding = true;
  std::string ssid = shill_property_util::GetSSIDFromProperties(
      *shill_dictionary_, false /* verbose_logging */, &unknown_encoding);
  if (!unknown_encoding && !ssid.empty())
    onc_object_->SetStringWithoutPathExpansion(::onc::wifi::kSSID, ssid);

  bool link_monitor_disable;
  if (shill_dictionary_->GetBooleanWithoutPathExpansion(
          shill::kLinkMonitorDisableProperty, &link_monitor_disable)) {
    onc_object_->SetBooleanWithoutPathExpansion(
        ::onc::wifi::kAllowGatewayARPPolling, !link_monitor_disable);
  }

  CopyPropertiesAccordingToSignature();
  TranslateAndAddNestedObject(::onc::wifi::kEAP);
}

void ShillToONCTranslator::TranslateWiMAXWithState() {
  CopyPropertiesAccordingToSignature();
  TranslateAndAddNestedObject(::onc::wimax::kEAP);
}

void ShillToONCTranslator::TranslateCellularWithState() {
  CopyPropertiesAccordingToSignature();
  TranslateWithTableAndSet(shill::kActivationStateProperty,
                           kActivationStateTable,
                           ::onc::cellular::kActivationState);
  TranslateWithTableAndSet(shill::kNetworkTechnologyProperty,
                           kNetworkTechnologyTable,
                           ::onc::cellular::kNetworkTechnology);
  const base::DictionaryValue* dictionary = NULL;
  if (shill_dictionary_->GetDictionaryWithoutPathExpansion(
          shill::kServingOperatorProperty, &dictionary)) {
    TranslateAndAddNestedObject(::onc::cellular::kServingOperator, *dictionary);
  }
  if (shill_dictionary_->GetDictionaryWithoutPathExpansion(
          shill::kCellularApnProperty, &dictionary)) {
    TranslateAndAddNestedObject(::onc::cellular::kAPN, *dictionary);
  }
  if (shill_dictionary_->GetDictionaryWithoutPathExpansion(
          shill::kCellularLastGoodApnProperty, &dictionary)) {
    TranslateAndAddNestedObject(::onc::cellular::kLastGoodAPN, *dictionary);
  }
  if (shill_dictionary_->GetDictionaryWithoutPathExpansion(
          shill::kPaymentPortalProperty, &dictionary)) {
    TranslateAndAddNestedObject(::onc::cellular::kPaymentPortal, *dictionary);
  }

  const base::DictionaryValue* device_dictionary = NULL;
  bool requires_roaming = false;
  shill_dictionary_->GetDictionaryWithoutPathExpansion(shill::kDeviceProperty,
                                                       &device_dictionary);
  if (device_dictionary) {
    // Merge the Device dictionary with this one (Cellular) using the
    // CellularDevice signature.
    ShillToONCTranslator nested_translator(
        *device_dictionary, onc_source_, kCellularWithStateSignature,
        kCellularDeviceTable, network_state_);
    std::unique_ptr<base::DictionaryValue> nested_object =
        nested_translator.CreateTranslatedONCObject();
    onc_object_->MergeDictionary(nested_object.get());

    /// Get the requires_roaming from the Device dictionary.
    device_dictionary->GetBooleanWithoutPathExpansion(
        shill::kProviderRequiresRoamingProperty, &requires_roaming);
  }
  if (requires_roaming) {
    onc_object_->SetStringWithoutPathExpansion(
        ::onc::cellular::kRoamingState, ::onc::cellular::kRoamingRequired);
  } else {
    TranslateWithTableAndSet(shill::kRoamingStateProperty, kRoamingStateTable,
                             ::onc::cellular::kRoamingState);
  }
}

void ShillToONCTranslator::TranslateCellularDevice() {
  CopyPropertiesAccordingToSignature();
  const base::DictionaryValue* shill_sim_lock_status = NULL;
  if (shill_dictionary_->GetDictionaryWithoutPathExpansion(
          shill::kSIMLockStatusProperty, &shill_sim_lock_status)) {
    TranslateAndAddNestedObject(::onc::cellular::kSIMLockStatus,
                                *shill_sim_lock_status);
  }
  const base::DictionaryValue* shill_home_provider = NULL;
  if (shill_dictionary_->GetDictionaryWithoutPathExpansion(
          shill::kHomeProviderProperty, &shill_home_provider)) {
    TranslateAndAddNestedObject(::onc::cellular::kHomeProvider,
                                *shill_home_provider);
  }
  const base::ListValue* shill_apns = NULL;
  if (shill_dictionary_->GetListWithoutPathExpansion(
          shill::kCellularApnListProperty, &shill_apns)) {
    TranslateAndAddListOfObjects(::onc::cellular::kAPNList, *shill_apns);
  }
  const base::ListValue* shill_found_networks = NULL;
  if (shill_dictionary_->GetListWithoutPathExpansion(
          shill::kFoundNetworksProperty, &shill_found_networks)) {
    TranslateAndAddListOfObjects(::onc::cellular::kFoundNetworks,
                                 *shill_found_networks);
  }
}

void ShillToONCTranslator::TranslateNetworkWithState() {
  CopyPropertiesAccordingToSignature();

  std::string shill_network_type;
  shill_dictionary_->GetStringWithoutPathExpansion(shill::kTypeProperty,
                                                   &shill_network_type);
  std::string onc_network_type = ::onc::network_type::kEthernet;
  if (shill_network_type != shill::kTypeEthernet &&
      shill_network_type != shill::kTypeEthernetEap) {
    TranslateStringToONC(kNetworkTypeTable, shill_network_type,
                         &onc_network_type);
  }
  // Translate nested Cellular, WiFi, etc. properties.
  if (!onc_network_type.empty()) {
    onc_object_->SetStringWithoutPathExpansion(::onc::network_config::kType,
                                               onc_network_type);
    TranslateAndAddNestedObject(onc_network_type);
  }

  // Since Name is a read only field in Shill unless it's a VPN, it is copied
  // here, but not when going the other direction (if it's not a VPN).
  std::string name;
  shill_dictionary_->GetStringWithoutPathExpansion(shill::kNameProperty, &name);
  onc_object_->SetStringWithoutPathExpansion(::onc::network_config::kName,
                                             name);

  // Limit ONC state to "NotConnected", "Connected", or "Connecting".
  std::string state;
  if (shill_dictionary_->GetStringWithoutPathExpansion(shill::kStateProperty,
                                                       &state)) {
    std::string onc_state = ::onc::connection_state::kNotConnected;
    if (NetworkState::StateIsConnected(state)) {
      onc_state = ::onc::connection_state::kConnected;
    } else if (NetworkState::StateIsConnecting(state)) {
      onc_state = ::onc::connection_state::kConnecting;
    }
    onc_object_->SetStringWithoutPathExpansion(
        ::onc::network_config::kConnectionState, onc_state);
    // Only set 'RestrictedConnectivity' if captive portal state is true.
    if (NetworkState::NetworkStateIsCaptivePortal(*shill_dictionary_)) {
      onc_object_->SetBooleanWithoutPathExpansion(
          ::onc::network_config::kRestrictedConnectivity, true);
    }
  }

  // 'ErrorState' reflects the most recent error maintained in NetworkState
  // (which may not match Shill's Error or PreviousError properties). Non
  // visible networks (with null network_state_) do not set ErrorState.
  if (network_state_) {
    std::string error_state = network_state_->GetErrorState();
    if (!error_state.empty()) {
      onc_object_->SetStringWithoutPathExpansion(
          ::onc::network_config::kErrorState, error_state);
    }
  }

  std::string profile_path;
  if (onc_source_ != ::onc::ONC_SOURCE_UNKNOWN &&
      shill_dictionary_->GetStringWithoutPathExpansion(shill::kProfileProperty,
                                                       &profile_path)) {
    std::string source;
    if (onc_source_ == ::onc::ONC_SOURCE_DEVICE_POLICY)
      source = ::onc::network_config::kSourceDevicePolicy;
    else if (onc_source_ == ::onc::ONC_SOURCE_USER_POLICY)
      source = ::onc::network_config::kSourceUserPolicy;
    else if (profile_path == NetworkProfileHandler::GetSharedProfilePath())
      source = ::onc::network_config::kSourceDevice;
    else if (!profile_path.empty())
      source = ::onc::network_config::kSourceUser;
    else
      source = ::onc::network_config::kSourceNone;
    onc_object_->SetStringWithoutPathExpansion(::onc::network_config::kSource,
                                               source);
  }

  // Use a human-readable aa:bb format for any hardware MAC address. Note:
  // this property is provided by the caller but is not part of the Shill
  // Service properties (it is copied from the Device properties).
  std::string address;
  if (shill_dictionary_->GetStringWithoutPathExpansion(shill::kAddressProperty,
                                                       &address)) {
    onc_object_->SetStringWithoutPathExpansion(
        ::onc::network_config::kMacAddress,
        network_util::FormattedMacAddress(address));
  }

  // Shill's Service has an IPConfig property (note the singular), not an
  // IPConfigs property. However, we require the caller of the translation to
  // patch the Shill dictionary before passing it to the translator.
  const base::ListValue* shill_ipconfigs = NULL;
  if (shill_dictionary_->GetListWithoutPathExpansion(shill::kIPConfigsProperty,
                                                     &shill_ipconfigs)) {
    TranslateAndAddListOfObjects(::onc::network_config::kIPConfigs,
                                 *shill_ipconfigs);
  }

  const base::DictionaryValue* saved_ipconfig = nullptr;
  if (shill_dictionary_->GetDictionaryWithoutPathExpansion(
          shill::kSavedIPConfigProperty, &saved_ipconfig)) {
    TranslateAndAddNestedObject(::onc::network_config::kSavedIPConfig,
                                *saved_ipconfig);
  }

  // Translate the StaticIPConfig object and set the IP config types.
  const base::DictionaryValue* static_ipconfig = nullptr;
  if (shill_dictionary_->GetDictionaryWithoutPathExpansion(
          shill::kStaticIPConfigProperty, &static_ipconfig)) {
    std::string ip_address;
    if (static_ipconfig->GetStringWithoutPathExpansion(shill::kAddressProperty,
                                                       &ip_address) &&
        !ip_address.empty()) {
      onc_object_->SetStringWithoutPathExpansion(
          ::onc::network_config::kIPAddressConfigType,
          ::onc::network_config::kIPConfigTypeStatic);
    }
    const base::ListValue* name_servers = nullptr;
    if (static_ipconfig->GetListWithoutPathExpansion(
            shill::kNameServersProperty, &name_servers) &&
        !name_servers->empty()) {
      onc_object_->SetStringWithoutPathExpansion(
          ::onc::network_config::kNameServersConfigType,
          ::onc::network_config::kIPConfigTypeStatic);
    }
    if (!ip_address.empty() || (name_servers && !name_servers->empty())) {
      TranslateAndAddNestedObject(::onc::network_config::kStaticIPConfig,
                                  *static_ipconfig);
    }
  }

  std::string proxy_config_str;
  if (shill_dictionary_->GetStringWithoutPathExpansion(
          shill::kProxyConfigProperty, &proxy_config_str) &&
      !proxy_config_str.empty()) {
    std::unique_ptr<base::DictionaryValue> proxy_config_value(
        ReadDictionaryFromJson(proxy_config_str));
    if (proxy_config_value) {
      std::unique_ptr<base::DictionaryValue> proxy_settings =
          ConvertProxyConfigToOncProxySettings(std::move(proxy_config_value));
      if (proxy_settings) {
        onc_object_->SetWithoutPathExpansion(
            ::onc::network_config::kProxySettings, std::move(proxy_settings));
      }
    }
  }
}

void ShillToONCTranslator::TranslateIPConfig() {
  CopyPropertiesAccordingToSignature();
  std::string shill_ip_method;
  shill_dictionary_->GetStringWithoutPathExpansion(shill::kMethodProperty,
                                                   &shill_ip_method);
  std::string type;
  if (shill_ip_method == shill::kTypeIPv4 ||
      shill_ip_method == shill::kTypeDHCP) {
    type = ::onc::ipconfig::kIPv4;
  } else if (shill_ip_method == shill::kTypeIPv6 ||
             shill_ip_method == shill::kTypeDHCP6) {
    type = ::onc::ipconfig::kIPv6;
  } else {
    return;  // Ignore unhandled IPConfig types, e.g. bootp, zeroconf, ppp
  }

  onc_object_->SetStringWithoutPathExpansion(::onc::ipconfig::kType, type);
}

void ShillToONCTranslator::TranslateSavedOrStaticIPConfig() {
  CopyPropertiesAccordingToSignature();

  // Static and Saved IPConfig in Shill are always of type IPv4. Set this type
  // in ONC, but not if the object would be empty except the type.
  if (!onc_object_->empty()) {
    onc_object_->SetStringWithoutPathExpansion(::onc::ipconfig::kType,
                                               ::onc::ipconfig::kIPv4);
  }
}

void ShillToONCTranslator::TranslateSavedIPConfig() {
  TranslateSavedOrStaticIPConfig();
}

void ShillToONCTranslator::TranslateStaticIPConfig() {
  TranslateSavedOrStaticIPConfig();
}

void ShillToONCTranslator::TranslateEap() {
  CopyPropertiesAccordingToSignature();

  // Translate EAP Outer and Inner values if EAP.EAP exists and is not empty.
  std::string shill_eap;
  if (shill_dictionary_->GetStringWithoutPathExpansion(
          shill::kEapMethodProperty, &shill_eap) &&
      !shill_eap.empty()) {
    TranslateWithTableAndSet(shill::kEapMethodProperty, kEAPOuterTable,
                             ::onc::eap::kOuter);
    TranslateWithTableAndSet(shill::kEapPhase2AuthProperty,
                             kEAP_TTLS_InnerTable, ::onc::eap::kInner);
  }
}

void ShillToONCTranslator::TranslateAndAddNestedObject(
    const std::string& onc_field_name) {
  TranslateAndAddNestedObject(onc_field_name, *shill_dictionary_);
}

void ShillToONCTranslator::TranslateAndAddNestedObject(
    const std::string& onc_field_name,
    const base::DictionaryValue& dictionary) {
  const OncFieldSignature* field_signature =
      GetFieldSignature(*onc_signature_, onc_field_name);
  if (!field_signature) {
    NOTREACHED() << "Unable to find signature for field: " << onc_field_name;
    return;
  }
  ShillToONCTranslator nested_translator(dictionary, onc_source_,
                                         *field_signature->value_signature,
                                         network_state_);
  std::unique_ptr<base::DictionaryValue> nested_object =
      nested_translator.CreateTranslatedONCObject();
  if (nested_object->empty())
    return;
  onc_object_->SetWithoutPathExpansion(onc_field_name,
                                       std::move(nested_object));
}

void ShillToONCTranslator::SetNestedOncValue(
    const std::string& onc_dictionary_name,
    const std::string& onc_field_name,
    const base::Value& value) {
  base::DictionaryValue* nested = nullptr;
  if (!onc_object_->GetDictionaryWithoutPathExpansion(onc_dictionary_name,
                                                      &nested)) {
    nested = onc_object_->SetDictionaryWithoutPathExpansion(
        onc_dictionary_name, base::MakeUnique<base::DictionaryValue>());
  }
  nested->SetWithoutPathExpansion(onc_field_name,
                                  base::MakeUnique<base::Value>(value));
}

void ShillToONCTranslator::TranslateAndAddListOfObjects(
    const std::string& onc_field_name,
    const base::ListValue& list) {
  const OncFieldSignature* field_signature =
      GetFieldSignature(*onc_signature_, onc_field_name);
  if (field_signature->value_signature->onc_type != base::Value::Type::LIST) {
    LOG(ERROR) << "ONC Field name: '" << onc_field_name << "' has type '"
               << field_signature->value_signature->onc_type
               << "', expected: base::Value::Type::LIST: " << GetName();
    return;
  }
  DCHECK(field_signature->value_signature->onc_array_entry_signature);
  std::unique_ptr<base::ListValue> result(new base::ListValue());
  for (base::ListValue::const_iterator it = list.begin(); it != list.end();
       ++it) {
    const base::DictionaryValue* shill_value = NULL;
    if (!it->GetAsDictionary(&shill_value))
      continue;
    ShillToONCTranslator nested_translator(
        *shill_value, onc_source_,
        *field_signature->value_signature->onc_array_entry_signature,
        network_state_);
    std::unique_ptr<base::DictionaryValue> nested_object =
        nested_translator.CreateTranslatedONCObject();
    // If the nested object couldn't be parsed, simply omit it.
    if (nested_object->empty())
      continue;
    result->Append(std::move(nested_object));
  }
  // If there are no entries in the list, there is no need to expose this field.
  if (result->empty())
    return;
  onc_object_->SetWithoutPathExpansion(onc_field_name, std::move(result));
}

void ShillToONCTranslator::CopyPropertiesAccordingToSignature() {
  CopyPropertiesAccordingToSignature(onc_signature_);
}

void ShillToONCTranslator::CopyPropertiesAccordingToSignature(
    const OncValueSignature* value_signature) {
  if (value_signature->base_signature)
    CopyPropertiesAccordingToSignature(value_signature->base_signature);
  if (!value_signature->fields)
    return;
  for (const OncFieldSignature* field_signature = value_signature->fields;
       field_signature->onc_field_name != NULL; ++field_signature) {
    CopyProperty(field_signature);
  }
}

void ShillToONCTranslator::CopyProperty(
    const OncFieldSignature* field_signature) {
  std::string shill_property_name;
  const base::Value* shill_value = NULL;
  if (!field_translation_table_ ||
      !GetShillPropertyName(field_signature->onc_field_name,
                            field_translation_table_, &shill_property_name) ||
      !shill_dictionary_->GetWithoutPathExpansion(shill_property_name,
                                                  &shill_value)) {
    return;
  }

  if (shill_value->GetType() != field_signature->value_signature->onc_type) {
    LOG(ERROR) << "Shill property '" << shill_property_name << "' with value "
               << *shill_value << " has base::Value::Type "
               << shill_value->GetType() << " but ONC field '"
               << field_signature->onc_field_name << "' requires type "
               << field_signature->value_signature->onc_type << ": "
               << GetName();
    return;
  }

  onc_object_->SetWithoutPathExpansion(
      field_signature->onc_field_name,
      base::MakeUnique<base::Value>(*shill_value));
}

void ShillToONCTranslator::TranslateWithTableAndSet(
    const std::string& shill_property_name,
    const StringTranslationEntry table[],
    const std::string& onc_field_name) {
  std::string shill_value;
  if (!shill_dictionary_->GetStringWithoutPathExpansion(shill_property_name,
                                                        &shill_value)) {
    return;
  }
  std::string onc_value;
  if (TranslateStringToONC(table, shill_value, &onc_value)) {
    onc_object_->SetStringWithoutPathExpansion(onc_field_name, onc_value);
    return;
  }
  LOG(ERROR) << "Shill property '" << shill_property_name << "' with value "
             << shill_value << " couldn't be translated to ONC: " << GetName();
}

std::string ShillToONCTranslator::GetName() {
  DCHECK(shill_dictionary_);
  std::string name;
  shill_dictionary_->GetStringWithoutPathExpansion(shill::kNameProperty, &name);
  return name;
}

}  // namespace

std::unique_ptr<base::DictionaryValue> TranslateShillServiceToONCPart(
    const base::DictionaryValue& shill_dictionary,
    ::onc::ONCSource onc_source,
    const OncValueSignature* onc_signature,
    const NetworkState* network_state) {
  CHECK(onc_signature != NULL);

  ShillToONCTranslator translator(shill_dictionary, onc_source, *onc_signature,
                                  network_state);
  return translator.CreateTranslatedONCObject();
}

}  // namespace onc
}  // namespace chromeos
