//
// Copyright (C) 2012 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#ifndef SHILL_CONNECTIVITY_TRIAL_H_
#define SHILL_CONNECTIVITY_TRIAL_H_

#include <memory>
#include <string>

#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/net/shill_time.h"
#include "shill/net/sockets.h"
#include "shill/refptr_types.h"

namespace shill {

class ByteString;
class EventDispatcher;

// 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, 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_;
  std::string url_string_;
  base::CancelableClosure trial_;
  base::CancelableClosure trial_timeout_;
  bool is_active_;
};

}  // namespace shill

#endif  // SHILL_CONNECTIVITY_TRIAL_H_
