// 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 NET_PROXY_PROXY_SCRIPT_DECIDER_H_
#define NET_PROXY_PROXY_SCRIPT_DECIDER_H_

#include <string>
#include <vector>

#include "base/memory/ref_counted.h"
#include "base/strings/string16.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "net/base/address_list.h"
#include "net/base/completion_callback.h"
#include "net/base/net_export.h"
#include "net/dns/host_resolver.h"
#include "net/dns/single_request_host_resolver.h"
#include "net/log/net_log.h"
#include "net/proxy/proxy_config.h"
#include "net/proxy/proxy_resolver.h"
#include "url/gurl.h"

namespace net {

class DhcpProxyScriptFetcher;
class NetLogParameter;
class ProxyResolver;
class ProxyScriptFetcher;

// ProxyScriptDecider is a helper class used by ProxyService to determine which
// PAC script to use given our proxy configuration.
//
// This involves trying to use PAC scripts in this order:
//
//   (1) WPAD (DHCP) if auto-detect is on.
//   (2) WPAD (DNS) if auto-detect is on.
//   (3) Custom PAC script if a URL was given.
//
// If no PAC script was successfully selected, then it fails with either a
// network error, or PAC_SCRIPT_FAILED (indicating it did not pass our
// validation).
//
// On successful completion, the fetched PAC script data can be accessed using
// script_data().
//
// Deleting ProxyScriptDecider while Init() is in progress, will
// cancel the request.
//
class NET_EXPORT_PRIVATE ProxyScriptDecider {
 public:
  // |proxy_script_fetcher|, |dhcp_proxy_script_fetcher| and
  // |net_log| must remain valid for the lifespan of ProxyScriptDecider.
  ProxyScriptDecider(ProxyScriptFetcher* proxy_script_fetcher,
                     DhcpProxyScriptFetcher* dhcp_proxy_script_fetcher,
                     NetLog* net_log);

  // Aborts any in-progress request.
  ~ProxyScriptDecider();

  // Evaluates the effective proxy settings for |config|, and downloads the
  // associated PAC script.
  // If |wait_delay| is positive, the initialization will pause for this
  // amount of time before getting started.
  // On successful completion, the "effective" proxy settings we ended up
  // deciding on will be available vial the effective_settings() accessor.
  // Note that this may differ from |config| since we will have stripped any
  // manual settings, and decided whether to use auto-detect or the custom PAC
  // URL. Finally, if auto-detect was used we may now have resolved that to a
  // specific script URL.
  int Start(const ProxyConfig& config,
            const base::TimeDelta wait_delay,
            bool fetch_pac_bytes,
            const CompletionCallback& callback);

  const ProxyConfig& effective_config() const;

  // TODO(eroman): Return a const-pointer.
  ProxyResolverScriptData* script_data() const;

  void set_quick_check_enabled(bool enabled) {
    quick_check_enabled_ = enabled;
  }

  bool quick_check_enabled() const { return quick_check_enabled_; }

 private:
  // Represents the sources from which we can get PAC files; two types of
  // auto-detect or a custom URL.
  struct PacSource {
    enum Type {
      WPAD_DHCP,
      WPAD_DNS,
      CUSTOM
    };

    PacSource(Type type, const GURL& url)
        : type(type), url(url) {}

    // Returns a Value representing the PacSource.  |effective_pac_url| must
    // be non-NULL and point to the URL derived from information contained in
    // |this|, if Type is not WPAD_DHCP.
    base::Value* NetLogCallback(const GURL* effective_pac_url,
                                NetLogCaptureMode capture_mode) const;

    Type type;
    GURL url;  // Empty unless |type == PAC_SOURCE_CUSTOM|.
  };

  typedef std::vector<PacSource> PacSourceList;

  enum State {
    STATE_NONE,
    STATE_WAIT,
    STATE_WAIT_COMPLETE,
    STATE_QUICK_CHECK,
    STATE_QUICK_CHECK_COMPLETE,
    STATE_FETCH_PAC_SCRIPT,
    STATE_FETCH_PAC_SCRIPT_COMPLETE,
    STATE_VERIFY_PAC_SCRIPT,
    STATE_VERIFY_PAC_SCRIPT_COMPLETE,
  };

  // Returns ordered list of PAC urls to try for |config|.
  PacSourceList BuildPacSourcesFallbackList(const ProxyConfig& config) const;

  void OnIOCompletion(int result);
  int DoLoop(int result);
  void DoCallback(int result);

  int DoWait();
  int DoWaitComplete(int result);

  int DoQuickCheck();
  int DoQuickCheckComplete(int result);

  int DoFetchPacScript();
  int DoFetchPacScriptComplete(int result);

  int DoVerifyPacScript();
  int DoVerifyPacScriptComplete(int result);

  // Tries restarting using the next fallback PAC URL:
  // |pac_sources_[++current_pac_source_index]|.
  // Returns OK and rewinds the state machine when there
  // is something to try, otherwise returns |error|.
  int TryToFallbackPacSource(int error);

  // Gets the initial state (we skip fetching when the
  // ProxyResolver doesn't |expect_pac_bytes()|.
  State GetStartState() const;

  void DetermineURL(const PacSource& pac_source, GURL* effective_pac_url);

  // Returns the current PAC URL we are fetching/testing.
  const PacSource& current_pac_source() const;

  void OnWaitTimerFired();
  void DidComplete();
  void Cancel();

  ProxyScriptFetcher* proxy_script_fetcher_;
  DhcpProxyScriptFetcher* dhcp_proxy_script_fetcher_;

  CompletionCallback callback_;

  size_t current_pac_source_index_;

  // Filled when the PAC script fetch completes.
  base::string16 pac_script_;

  // Flag indicating whether the caller requested a mandatory pac script
  // (i.e. fallback to direct connections are prohibited).
  bool pac_mandatory_;

  // Whether we have an existing custom PAC URL.
  bool have_custom_pac_url_;

  PacSourceList pac_sources_;
  State next_state_;

  BoundNetLog net_log_;

  bool fetch_pac_bytes_;

  base::TimeDelta wait_delay_;
  base::OneShotTimer<ProxyScriptDecider> wait_timer_;

  // Whether to do DNS quick check
  bool quick_check_enabled_;

  // Results.
  ProxyConfig effective_config_;
  scoped_refptr<ProxyResolverScriptData> script_data_;

  AddressList wpad_addresses_;
  base::OneShotTimer<ProxyScriptDecider> quick_check_timer_;
  scoped_ptr<SingleRequestHostResolver> host_resolver_;
  base::Time quick_check_start_time_;

  DISALLOW_COPY_AND_ASSIGN(ProxyScriptDecider);
};

}  // namespace net

#endif  // NET_PROXY_PROXY_SCRIPT_DECIDER_H_
