// 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.

#ifndef CHROME_BROWSER_CHROMEOS_PROXY_CONFIG_SERVICE_IMPL_H_
#define CHROME_BROWSER_CHROMEOS_PROXY_CONFIG_SERVICE_IMPL_H_

#include <string>
#include <vector>

#include "base/basictypes.h"
#include "base/values.h"
#include "chrome/browser/api/prefs/pref_member.h"
#include "chrome/browser/chromeos/cros/network_library.h"
#include "chrome/browser/net/pref_proxy_config_tracker_impl.h"

namespace chromeos {

// Implementation of proxy config service for chromeos that:
// - extends PrefProxyConfigTrackerImpl (and so lives and runs entirely on UI
//   thread) to handle proxy from prefs (via PrefProxyConfigTrackerImpl) and
//   system i.e. network (via shill notifications)
// - exists one per profile and one per local state
// - retrieves initial system proxy configuration from cros settings persisted
//   on chromeos device from chromeos revisions before migration to shill,
// - persists proxy setting per network in flimflim
// - provides network stack with latest effective proxy configuration for
//   currently active network via PrefProxyConfigTrackerImpl's mechanism of
//   pushing config to ChromeProxyConfigService
// - provides UI with methods to retrieve and modify proxy configuration for
//   any remembered network (either currently active or non-active) of current
//   user profile
class ProxyConfigServiceImpl
    : public PrefProxyConfigTrackerImpl,
      public NetworkLibrary::NetworkManagerObserver,
      public NetworkLibrary::NetworkObserver {
 public:
  // ProxyConfigServiceImpl is created in ProxyServiceFactory::
  // CreatePrefProxyConfigTrackerImpl via Profile::GetProxyConfigTracker() for
  // profile or IOThread constructor for local state and is owned by the
  // respective classes.
  //
  // From the UI, it is accessed via Profile::GetProxyConfigTracker to allow
  // user to read or modify the proxy configuration via UIGetProxyConfig or
  // UISetProxyConfigTo* respectively.
  // The new modified proxy config, together with proxy from prefs if available,
  // are used to determine the effective proxy config, which is then pushed
  // through PrefProxyConfigTrackerImpl to ChromeProxyConfigService to the
  // network stack.
  //
  // In contrary to other platforms which simply use the systems' UI to allow
  // users to configure proxies, we have to implement our own UI on the chromeos
  // device.  This requires extra and specific UI requirements that
  // net::ProxyConfig does not suffice.  So we create an augmented analog to
  // net:ProxyConfig here to include and handle these UI requirements, e.g.
  // - state of configuration e.g. where it was picked up from - policy,
  //   extension, etc (refer to ProxyPrefs::ConfigState)
  // - the read/write access of a proxy setting
  // - may add more stuff later.
  // This is then converted to the common net::ProxyConfig before being pushed
  // to PrefProxyConfigTrackerImpl::OnProxyConfigChanged and then to the network
  // stack.
  struct ProxyConfig {
    // Specifies if proxy config is direct, auto-detect, using pac script,
    // single-proxy, or proxy-per-scheme.
    enum Mode {
      MODE_DIRECT,
      MODE_AUTO_DETECT,
      MODE_PAC_SCRIPT,
      MODE_SINGLE_PROXY,
      MODE_PROXY_PER_SCHEME,
    };

    // Proxy setting for mode = direct or auto-detect or using pac script.
    struct AutomaticProxy {
      GURL pac_url;  // Set if proxy is using pac script.
    };

    // Proxy setting for mode = single-proxy or proxy-per-scheme.
    struct ManualProxy {
      net::ProxyServer server;
    };

    ProxyConfig();
    ~ProxyConfig();

    // Converts net::ProxyConfig to |this|.
    bool FromNetProxyConfig(const net::ProxyConfig& net_config);

    // Converts |this| to Dictionary of ProxyConfigDictionary format (which
    // is the same format used by prefs).
    DictionaryValue* ToPrefProxyConfig();

    // Map |scheme| (one of "http", "https", "ftp" or "socks") to the correct
    // ManualProxy.  Returns NULL if scheme is invalid.
    ManualProxy* MapSchemeToProxy(const std::string& scheme);

    // We've migrated device settings to shill, so we only need to
    // deserialize previously persisted device settings.
    // Deserializes from signed setting on device as std::string into a
    // protobuf and then into the config.
    bool DeserializeForDevice(const std::string& input);

    // Serializes config into a ProxyConfigDictionary and then std::string
    // persisted as string property in shill for a network.
    bool SerializeForNetwork(std::string* output);

    // Encodes the proxy server as "<url-scheme>=<proxy-scheme>://<proxy>"
    static void EncodeAndAppendProxyServer(const std::string& scheme,
                                           const net::ProxyServer& server,
                                           std::string* spec);

    Mode mode;

    ProxyPrefs::ConfigState state;

    // True if user can modify proxy settings via UI.
    // If proxy is managed by policy or extension or other_precde or is for
    // shared network but kUseSharedProxies is turned off, it can't be modified
    // by user.
    bool user_modifiable;

    // Set if mode is MODE_DIRECT or MODE_AUTO_DETECT or MODE_PAC_SCRIPT.
    AutomaticProxy  automatic_proxy;
    // Set if mode is MODE_SINGLE_PROXY.
    ManualProxy     single_proxy;
    // Set if mode is MODE_PROXY_PER_SCHEME and has http proxy.
    ManualProxy     http_proxy;
    // Set if mode is MODE_PROXY_PER_SCHEME and has https proxy.
    ManualProxy     https_proxy;
    // Set if mode is MODE_PROXY_PER_SCHEME and has ftp proxy.
    ManualProxy     ftp_proxy;
    // Set if mode is MODE_PROXY_PER_SCHEME and has socks proxy.
    ManualProxy     socks_proxy;

    // Exceptions for when not to use a proxy.
    net::ProxyBypassRules  bypass_rules;
  };

  // Constructor.
  explicit ProxyConfigServiceImpl(PrefService* pref_service);
  virtual ~ProxyConfigServiceImpl();

  // Called by UI to set service path of |network| to be displayed or edited.
  // Subsequent UISet* methods will use this network, until UI calls it again
  // with a different network.
  void UISetCurrentNetwork(const std::string& current_network);

  // Called from UI to make the currently active network the one to be displayed
  // or edited. Subsequent UISet* methods will use this network until UI calls
  // it again when the active network has changed.
  void UIMakeActiveNetworkCurrent();

  // Called from UI to get name of the current network set via
  // UISetCurrentNetwork or UIMakeActiveNetworkCurrent.
  void UIGetCurrentNetworkName(std::string* network_name);

  // Called from UI to retrieve proxy configuration in |current_ui_config_|.
  void UIGetProxyConfig(ProxyConfig* config);

  // Called from UI to update proxy configuration for different modes.
  // Returns true if config is set properly and persisted to shill for the
  // current network (set via UISetCurrentNetwork/UIMakeActiveNetworkCurrent).
  // If this network is also currently active, config service proceeds to start
  // activating it on network stack.
  // Returns false if config is not set properly, probably because information
  // is incomplete or invalid; while config service won't proceed to activate or
  // persist this config, the information is "cached" in the service, so that
  // the next UIGetProxyConfig call will return this latest information.
  bool UISetProxyConfigToDirect();
  bool UISetProxyConfigToAutoDetect();
  bool UISetProxyConfigToPACScript(const GURL& pac_url);
  bool UISetProxyConfigToSingleProxy(const net::ProxyServer& server);
  // |scheme| is one of "http", "https", "ftp" or "socks".
  bool UISetProxyConfigToProxyPerScheme(const std::string& scheme,
                                        const net::ProxyServer& server);
  // Only valid for MODE_SINGLE_PROXY or MODE_PROXY_PER_SCHEME.
  bool UISetProxyConfigBypassRules(const net::ProxyBypassRules& bypass_rules);

  // Add/Remove callback functions for notification when network to be viewed is
  // changed by the UI.
  void AddNotificationCallback(base::Closure callback);
  void RemoveNotificationCallback(base::Closure callback);

  // PrefProxyConfigTrackerImpl implementation.
  virtual void OnProxyConfigChanged(ProxyPrefs::ConfigState config_state,
                                    const net::ProxyConfig& config) OVERRIDE;

  // NetworkLibrary::NetworkManagerObserver implementation.
  virtual void OnNetworkManagerChanged(NetworkLibrary* cros) OVERRIDE;

  // NetworkLibrary::NetworkObserver implementation.
  virtual void OnNetworkChanged(NetworkLibrary* cros,
                                const Network* network) OVERRIDE;

  // Register UseShardProxies preference.
  static void RegisterPrefs(PrefService* pref_service);

#if defined(UNIT_TEST)
  void SetTesting(ProxyConfig* test_config) {
    UIMakeActiveNetworkCurrent();
    if (test_config) {
      std::string value;
      test_config->SerializeForNetwork(&value);
      SetProxyConfigForNetwork(active_network_, value, false);
    }
  }
#endif  // defined(UNIT_TEST)

 private:
  // content::NotificationObserver implementation.
  virtual void Observe(int type,
                       const content::NotificationSource& source,
                       const content::NotificationDetails& details) OVERRIDE;

  // Called from the various UISetProxyConfigTo*.
  void OnUISetProxyConfig();

  // Called from OnNetworkManagerChanged and OnNetworkChanged for currently
  // active network, to handle previously active network, new active network,
  // and if necessary, migrates device settings to shill and/or activates
  // proxy setting of new network.
  void OnActiveNetworkChanged(NetworkLibrary* cros,
                              const Network* active_network);

  // Sets proxy config for |network_path| into shill and activates setting
  // if the network is currently active.  If |only_set_if_empty| is true,
  // proxy will be set and saved only if network has no proxy.
  void SetProxyConfigForNetwork(const std::string& network_path,
                                const std::string& value,
                                bool only_set_if_empty);

  // Returns value of UseSharedProxies preference if it's not default, else
  // returns false if user is logged in and true otherwise.
  bool GetUseSharedProxies();

  // Determines effective proxy config based on prefs from config tracker,
  // |network| and if user is using shared proxies.
  // If |activate| is true, effective config is stored in |active_config_| and
  // activated on network stack, and hence, picked up by observers.
  // if |activate| is false, effective config is stored in |current_ui_config_|
  // but not activated on network stack, and hence, not picked up by observers.
  void DetermineEffectiveConfig(const Network* network, bool activate);

  // Determines |current_ui_config_| based on |network|, called from
  // UISetCurrentNetwork and UIMakeActiveNetworkActive.
  void OnUISetCurrentNetwork(const Network* network);

  // Returns true if proxy is to be ignored for network, which happens if
  // network is shared and use-shared-proxies is turned off.
  bool IgnoreProxy(const Network* network) {
    return network->profile_type() == PROFILE_SHARED && !GetUseSharedProxies();
  }

  // Reset UI cache variables that keep track of UI activities.
  void ResetUICache();

  void FetchProxyPolicy();

  // Data members.

  // Service path of currently active network (determined via shill
  // notifications); if effective proxy config is from system, proxy of this
  // network will be the one taking effect.
  std::string active_network_;

  // State of |active_config_|.  |active_config_| is only valid if
  // |active_config_state_| is not ProxyPrefs::CONFIG_UNSET.
  ProxyPrefs::ConfigState active_config_state_;

  // Active proxy configuration, which could be from prefs or network.
  net::ProxyConfig active_config_;

  // Proxy config retreived from device, in format generated from
  // SerializeForNetwork, that can be directly set into shill.
  std::string device_config_;

  // Service path of network whose proxy configuration is being displayed or
  // edited via UI, separate from |active_network_| which may be same or
  // different.
  std::string current_ui_network_;

  // Proxy configuration of |current_ui_network_|.
  ProxyConfig current_ui_config_;

  // Track changes in UseSharedProxies user preference.
  BooleanPrefMember use_shared_proxies_;

  // Callbacks for notification when network to be viewed has been changed from
  // the UI.
  std::vector<base::Closure> callbacks_;

  base::WeakPtrFactory<ProxyConfigServiceImpl> pointer_factory_;

  DISALLOW_COPY_AND_ASSIGN(ProxyConfigServiceImpl);
};

}  // namespace chromeos

#endif  // CHROME_BROWSER_CHROMEOS_PROXY_CONFIG_SERVICE_IMPL_H_
