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

#ifndef SHILL_CONNECTIVITY_TRIAL_H_
#define SHILL_CONNECTIVITY_TRIAL_H_

#include <memory>
#include <string>
#include <vector>

#include <base/callback.h>
#include <base/cancelable_callback.h>
#include <base/memory/ref_counted.h>
#include <base/memory/weak_ptr.h>
#include <gtest/gtest_prod.h>  // for FRIEND_TEST

#include "shill/http_request.h"
#include "shill/http_url.h"
#include "shill/refptr_types.h"
#include "shill/shill_time.h"
#include "shill/sockets.h"

namespace shill {

class ByteString;
class EventDispatcher;
class Time;

// The ConnectivityTrial class implements a single portal detection
// trial.  Each trial checks if a connection has "general internet
// connectivity."
//
// ConnectivityTrial is responsible for managing the callbacks between the
// calling class requesting a connectivity trial and the HTTPRequest that is
// used to test connectivity.  ConnectivityTrial maps between the HTTPRequest
// response codes to higher-level connection-oriented status.
//
// ConnectivityTrial tests the connection by attempting to parse and access a
// given URL.  Any result that deviates from the expected behavior (DNS or HTTP
// errors, as well as retrieved content errors, and timeouts) are considered
// failures.

class ConnectivityTrial {
 public:
  enum Phase {
    kPhaseConnection,
    kPhaseDNS,
    kPhaseHTTP,
    kPhaseContent,
    kPhaseUnknown
  };

  enum Status {
    kStatusFailure,
    kStatusSuccess,
    kStatusTimeout
  };

  struct Result {
    Result()
        : phase(kPhaseUnknown), status(kStatusFailure) {}
    Result(Phase phase_in, Status status_in)
        : phase(phase_in), status(status_in) {}
    Phase phase;
    Status status;
  };

  static const char kDefaultURL[];
  static const char kResponseExpected[];

  ConnectivityTrial(ConnectionRefPtr connection,
                    EventDispatcher *dispatcher,
                    int trial_timeout_seconds,
                    const base::Callback<void(Result)> &trial_callback);
  virtual ~ConnectivityTrial();

  // Static method used to map a portal detection phase tp a string.  This
  // includes the phases for connection, DNS, HTTP, returned content and
  // unknown.
  static const std::string PhaseToString(Phase phase);

  // Static method to map from the result of a portal detection phase to a
  // status string. This method supports success, timeout and failure.
  static const std::string StatusToString(Status status);

  // Static method mapping from HTTPRequest responses to ConntectivityTrial
  // phases for portal detection. For example, if the HTTPRequest result is
  // HTTPRequest::kResultDNSFailure, this method returns a
  // ConnectivityTrial::Result with the phase set to
  // ConnectivityTrial::kPhaseDNS and the status set to
  // ConnectivityTrial::kStatusFailure.
  static Result GetPortalResultForRequestResult(HTTPRequest::Result result);

  // Start a ConnectivityTrial with the supplied URL and starting delay (ms).
  // Returns trus if |url_string| correctly parses as a URL.  Returns false (and
  // does not start) if the |url_string| fails to parse.
  //
  // After a trial completes, the callback supplied in the constructor is
  // called.
  virtual bool Start(const std::string &url_string,
                     int start_delay_milliseconds);

  // After a trial completes, the calling class may call Retry on the trial.
  // This allows the underlying HTTPRequest object to be reused.  The URL is not
  // reparsed and the original URL supplied in the Start command is used.  The
  // |start_delay| is the time (ms) to wait before starting the trial.  Retry
  // returns true if the underlying HTTPRequest is still available.  If the
  // HTTPRequest was reset or never created, Retry will return false.
  virtual bool Retry(int start_delay_milliseconds);

  // End the current attempt if one is in progress.  Will not call the callback
  // with any intermediate results.
  // The ConnectivityTrial will cancel any existing scheduled tasks and destroy
  // the underlying HTTPRequest.
  virtual void Stop();

  // Method to return if the connection is being actively tested.
  virtual bool IsActive();

 private:
  friend class PortalDetectorTest;
  FRIEND_TEST(PortalDetectorTest, StartAttemptFailed);
  FRIEND_TEST(PortalDetectorTest, StartAttemptRepeated);
  FRIEND_TEST(PortalDetectorTest, StartAttemptAfterDelay);
  FRIEND_TEST(PortalDetectorTest, AttemptCount);
  FRIEND_TEST(PortalDetectorTest, ReadBadHeadersRetry);
  FRIEND_TEST(PortalDetectorTest, ReadBadHeader);
  friend class ConnectivityTrialTest;
  FRIEND_TEST(ConnectivityTrialTest, StartAttemptFailed);
  FRIEND_TEST(ConnectivityTrialTest, TrialRetry);
  FRIEND_TEST(ConnectivityTrialTest, ReadBadHeadersRetry);
  FRIEND_TEST(ConnectivityTrialTest, IsActive);

  // Start a ConnectivityTrial with the supplied delay in ms.
  void StartTrialAfterDelay(int start_delay_milliseconds);

  // Internal method used to start the actual connectivity trial, called after
  // the start delay completes.
  void StartTrialTask();

  // Callback used to return data read from the HTTPRequest.
  void RequestReadCallback(const ByteString &response_data);

  // Callback used to return the result of the HTTPRequest.
  void RequestResultCallback(HTTPRequest::Result result,
                             const ByteString &response_data);

  // Internal method used to clean up state and call the original caller that
  // created and triggered this ConnectivityTrial.
  void CompleteTrial(Result result);

  // Internal method used to cancel the timeout timer and stop an active
  // HTTPRequest.  If |reset_request| is true, this method resets the underlying
  // HTTPRequest object.
  void CleanupTrial(bool reset_request);

  // Callback used to cancel the underlying HTTPRequest in the event of a
  // timeout.
  void TimeoutTrialTask();

  ConnectionRefPtr connection_;
  EventDispatcher *dispatcher_;
  int trial_timeout_seconds_;
  base::Callback<void(Result)> trial_callback_;
  base::WeakPtrFactory<ConnectivityTrial> weak_ptr_factory_;
  base::Callback<void(const ByteString &)> request_read_callback_;
  base::Callback<void(HTTPRequest::Result, const ByteString &)>
        request_result_callback_;
  std::unique_ptr<HTTPRequest> request_;

  Sockets sockets_;
  HTTPURL url_;
  base::CancelableClosure trial_;
  base::CancelableClosure trial_timeout_;
  bool is_active_;
};

}  // namespace shill

#endif  // SHILL_CONNECTIVITY_TRIAL_H_
