// 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 "chrome/browser/chromeos/proxy_config_service_impl.h"

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/prefs/pref_service.h"
#include "base/values.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chromeos/login/user_manager.h"
#include "chrome/browser/chromeos/net/proxy_config_handler.h"
#include "chrome/browser/policy/browser_policy_connector.h"
#include "chrome/browser/policy/cloud/cloud_policy_constants.h"
#include "chrome/browser/prefs/proxy_config_dictionary.h"
#include "chrome/browser/prefs/proxy_prefs.h"
#include "chrome/common/pref_names.h"
#include "chromeos/network/favorite_state.h"
#include "chromeos/network/network_profile.h"
#include "chromeos/network/network_profile_handler.h"
#include "chromeos/network/network_state.h"
#include "chromeos/network/network_state_handler.h"
#include "chromeos/network/onc/onc_utils.h"

namespace chromeos {

namespace {

// Writes the proxy config of |network| to |proxy_config|.  Set |onc_source| to
// the source of this configuration. Returns false if no
// proxy was configured for this network.
bool GetProxyConfig(const PrefService* profile_prefs,
                    const PrefService* local_state_prefs,
                    const FavoriteState& network,
                    net::ProxyConfig* proxy_config,
                    ::onc::ONCSource* onc_source) {
  scoped_ptr<ProxyConfigDictionary> proxy_dict =
      proxy_config::GetProxyConfigForFavoriteNetwork(
          profile_prefs, local_state_prefs, network, onc_source);
  if (!proxy_dict)
    return false;
  return PrefProxyConfigTrackerImpl::PrefConfigToNetConfig(*proxy_dict,
                                                           proxy_config);
}

}  // namespace

ProxyConfigServiceImpl::ProxyConfigServiceImpl(PrefService* profile_prefs,
                                               PrefService* local_state_prefs)
    : PrefProxyConfigTrackerImpl(profile_prefs ? profile_prefs
                                               : local_state_prefs),
      active_config_state_(ProxyPrefs::CONFIG_UNSET),
      profile_prefs_(profile_prefs),
      local_state_prefs_(local_state_prefs),
      pointer_factory_(this) {
  const base::Closure proxy_change_callback = base::Bind(
      &ProxyConfigServiceImpl::OnProxyPrefChanged, base::Unretained(this));

  if (profile_prefs) {
    profile_pref_registrar_.Init(profile_prefs);
    profile_pref_registrar_.Add(prefs::kOpenNetworkConfiguration,
                                proxy_change_callback);
    profile_pref_registrar_.Add(prefs::kUseSharedProxies,
                                proxy_change_callback);
  }
  local_state_pref_registrar_.Init(local_state_prefs);
  local_state_pref_registrar_.Add(prefs::kDeviceOpenNetworkConfiguration,
                                  proxy_change_callback);

  // Register for changes to the default network.
  NetworkStateHandler* state_handler =
      NetworkHandler::Get()->network_state_handler();
  state_handler->AddObserver(this, FROM_HERE);
  DefaultNetworkChanged(state_handler->DefaultNetwork());
}

ProxyConfigServiceImpl::~ProxyConfigServiceImpl() {
  if (NetworkHandler::IsInitialized()) {
    NetworkHandler::Get()->network_state_handler()->RemoveObserver(
        this, FROM_HERE);
  }
}

void ProxyConfigServiceImpl::OnProxyConfigChanged(
    ProxyPrefs::ConfigState config_state,
    const net::ProxyConfig& config) {
  VLOG(1) << "Got prefs change: "
          << ProxyPrefs::ConfigStateToDebugString(config_state)
          << ", mode=" << config.proxy_rules().type;
  DetermineEffectiveConfigFromDefaultNetwork();
}

void ProxyConfigServiceImpl::OnProxyPrefChanged() {
  DetermineEffectiveConfigFromDefaultNetwork();
}

void ProxyConfigServiceImpl::DefaultNetworkChanged(
    const NetworkState* new_network) {
  std::string new_network_path;
  if (new_network)
    new_network_path = new_network->path();

  VLOG(1) << "DefaultNetworkChanged to '" << new_network_path << "'.";
  VLOG_IF(1, new_network) << "New network: name=" << new_network->name()
                          << ", profile=" << new_network->profile_path();

  // Even if the default network is the same, its proxy config (e.g. if private
  // version of network replaces the shared version after login), or
  // use-shared-proxies setting (e.g. after login) may have changed, so
  // re-determine effective proxy config, and activate if different.
  DetermineEffectiveConfigFromDefaultNetwork();
}

// static
bool ProxyConfigServiceImpl::IgnoreProxy(const PrefService* profile_prefs,
                                         const std::string network_profile_path,
                                         ::onc::ONCSource onc_source) {
  if (!profile_prefs) {
    // If the profile preference are not available, this must be the object
    // associated to local state used for system requests or login-profile. Make
    // sure that proxies are enabled.
    VLOG(1) << "Use proxy for system requests and sign-in screen.";
    return false;
  }

  if (network_profile_path.empty())
    return true;

  const NetworkProfile* profile = NetworkHandler::Get()
      ->network_profile_handler()->GetProfileForPath(network_profile_path);
  if (!profile) {
    LOG(WARNING) << "Unknown profile_path '" << network_profile_path
                 << "'. Ignoring proxy.";
    return true;
  }
  if (profile->type() == NetworkProfile::TYPE_USER) {
    VLOG(1) << "Respect proxy of not-shared networks.";
    return false;
  }
  if (onc_source == ::onc::ONC_SOURCE_DEVICE_POLICY) {
    policy::BrowserPolicyConnector* connector =
        g_browser_process->browser_policy_connector();
    const User* logged_in_user = UserManager::Get()->GetLoggedInUser();
    if (connector->GetUserAffiliation(logged_in_user->email()) ==
        policy::USER_AFFILIATION_MANAGED) {
      VLOG(1) << "Respecting proxy for network, as logged-in user belongs to "
              << "the domain the device is enrolled to.";
      return false;
    }
  }

  // This network is shared and not managed by the user's domain.
  bool use_shared_proxies = profile_prefs->GetBoolean(prefs::kUseSharedProxies);
  VLOG(1) << "Use proxy of shared network: " << use_shared_proxies;
  return !use_shared_proxies;
}

void ProxyConfigServiceImpl::DetermineEffectiveConfigFromDefaultNetwork() {
  NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
  const FavoriteState* network = handler->DefaultFavoriteNetwork();

  // Get prefs proxy config if available.
  net::ProxyConfig pref_config;
  ProxyPrefs::ConfigState pref_state = GetProxyConfig(&pref_config);

  // Get network proxy config if available.
  net::ProxyConfig network_config;
  net::ProxyConfigService::ConfigAvailability network_availability =
      net::ProxyConfigService::CONFIG_UNSET;
  bool ignore_proxy = true;
  if (network) {
    ::onc::ONCSource onc_source = ::onc::ONC_SOURCE_NONE;
    const bool network_proxy_configured = chromeos::GetProxyConfig(
        prefs(), local_state_prefs_, *network, &network_config, &onc_source);
    ignore_proxy =
        IgnoreProxy(profile_prefs_, network->profile_path(), onc_source);

    // If network is shared but use-shared-proxies is off, use direct mode.
    if (ignore_proxy) {
      network_config = net::ProxyConfig();
      network_availability = net::ProxyConfigService::CONFIG_VALID;
    } else if (network_proxy_configured) {
      // Network is private or shared with user using shared proxies.
      VLOG(1) << this << ": using proxy of network " << network->path();
      network_availability = net::ProxyConfigService::CONFIG_VALID;
    }
  }

  // Determine effective proxy config, either from prefs or network.
  ProxyPrefs::ConfigState effective_config_state;
  net::ProxyConfig effective_config;
  GetEffectiveProxyConfig(pref_state, pref_config,
                          network_availability, network_config, ignore_proxy,
                          &effective_config_state, &effective_config);

  // Activate effective proxy and store into |active_config_|.
  // If last update didn't complete, we definitely update now.
  bool update_now = update_pending();
  if (!update_now) {  // Otherwise, only update now if there're changes.
    update_now = active_config_state_ != effective_config_state ||
                 (active_config_state_ != ProxyPrefs::CONFIG_UNSET &&
                  !active_config_.Equals(effective_config));
  }
  if (update_now) {  // Activate and store new effective config.
    active_config_state_ = effective_config_state;
    if (active_config_state_ != ProxyPrefs::CONFIG_UNSET)
      active_config_ = effective_config;
    // If effective config is from system (i.e. network), it's considered a
    // special kind of prefs that ranks below policy/extension but above
    // others, so bump it up to CONFIG_OTHER_PRECEDE to force its precedence
    // when PrefProxyConfigTrackerImpl pushes it to ChromeProxyConfigService.
    if (effective_config_state == ProxyPrefs::CONFIG_SYSTEM)
      effective_config_state = ProxyPrefs::CONFIG_OTHER_PRECEDE;
    // If config is manual, add rule to bypass local host.
    if (effective_config.proxy_rules().type !=
        net::ProxyConfig::ProxyRules::TYPE_NO_RULES) {
      effective_config.proxy_rules().bypass_rules.AddRuleToBypassLocal();
    }
    PrefProxyConfigTrackerImpl::OnProxyConfigChanged(effective_config_state,
                                                     effective_config);
    if (VLOG_IS_ON(1) && !update_pending()) {  // Update was successful.
      scoped_ptr<base::DictionaryValue> config_dict(effective_config.ToValue());
      VLOG(1) << this << ": Proxy changed: "
              << ProxyPrefs::ConfigStateToDebugString(active_config_state_)
              << ", " << *config_dict;
    }
  }
}

}  // namespace chromeos
