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

#include "shill/portal_detector.h"

#include <string>

#include <base/bind.h>
#include <base/string_number_conversions.h>
#include <base/string_util.h>
#include <base/stringprintf.h>

#include "shill/async_connection.h"
#include "shill/connection.h"
#include "shill/dns_client.h"
#include "shill/event_dispatcher.h"
#include "shill/http_url.h"
#include "shill/ip_address.h"
#include "shill/logging.h"
#include "shill/sockets.h"

using base::Bind;
using base::Callback;
using base::StringPrintf;
using std::string;

namespace shill {

const int PortalDetector::kDefaultCheckIntervalSeconds = 30;
const char PortalDetector::kDefaultCheckPortalList[] = "ethernet,wifi,cellular";
const char PortalDetector::kDefaultURL[] =
    "http://clients3.google.com/generate_204";
const char PortalDetector::kResponseExpected[] = "HTTP/?.? 204";

const int PortalDetector::kMaxRequestAttempts = 3;
const int PortalDetector::kMinTimeBetweenAttemptsSeconds = 3;
const int PortalDetector::kRequestTimeoutSeconds = 10;
const int PortalDetector::kMaxFailuresInContentPhase = 2;

const char PortalDetector::kPhaseConnectionString[] = "Connection";
const char PortalDetector::kPhaseDNSString[] = "DNS";
const char PortalDetector::kPhaseHTTPString[] = "HTTP";
const char PortalDetector::kPhaseContentString[] = "Content";
const char PortalDetector::kPhaseUnknownString[] = "Unknown";

const char PortalDetector::kStatusFailureString[] = "Failure";
const char PortalDetector::kStatusSuccessString[] = "Success";
const char PortalDetector::kStatusTimeoutString[] = "Timeout";

PortalDetector::PortalDetector(
    ConnectionRefPtr connection,
    EventDispatcher *dispatcher,
    const Callback<void(const Result &)> &callback)
    : attempt_count_(0),
      attempt_start_time_((struct timeval){0}),
      connection_(connection),
      dispatcher_(dispatcher),
      weak_ptr_factory_(this),
      portal_result_callback_(callback),
      request_read_callback_(
          Bind(&PortalDetector::RequestReadCallback,
               weak_ptr_factory_.GetWeakPtr())),
      request_result_callback_(
          Bind(&PortalDetector::RequestResultCallback,
               weak_ptr_factory_.GetWeakPtr())),
      time_(Time::GetInstance()),
      failures_in_content_phase_(0) { }

PortalDetector::~PortalDetector() {
  Stop();
}

bool PortalDetector::Start(const string &url_string) {
  return StartAfterDelay(url_string, 0);
}

bool PortalDetector::StartAfterDelay(const string &url_string,
                                     int delay_seconds) {
  SLOG(Portal, 3) << "In " << __func__;

  DCHECK(!request_.get());

  if (!url_.ParseFromString(url_string)) {
    LOG(ERROR) << "Failed to parse URL string: " << url_string;
    return false;
  }

  request_.reset(new HTTPRequest(connection_, dispatcher_, &sockets_));
  attempt_count_ = 0;
  // If we're starting a new set of attempts, discard past failure history.
  failures_in_content_phase_ = 0;
  StartAttempt(delay_seconds);
  return true;
}

void PortalDetector::Stop() {
  SLOG(Portal, 3) << "In " << __func__;

  if (!request_.get()) {
    return;
  }

  start_attempt_.Cancel();
  StopAttempt();
  attempt_count_ = 0;
  failures_in_content_phase_ = 0;
  request_.reset();
}

bool PortalDetector::IsInProgress() {
  return attempt_count_ != 0;
}

// static
const string PortalDetector::PhaseToString(Phase phase) {
  switch (phase) {
    case kPhaseConnection:
      return kPhaseConnectionString;
    case kPhaseDNS:
      return kPhaseDNSString;
    case kPhaseHTTP:
      return kPhaseHTTPString;
    case kPhaseContent:
      return kPhaseContentString;
    case kPhaseUnknown:
    default:
      return kPhaseUnknownString;
  }
}

// static
const string PortalDetector::StatusToString(Status status) {
  switch (status) {
    case kStatusSuccess:
      return kStatusSuccessString;
    case kStatusTimeout:
      return kStatusTimeoutString;
    case kStatusFailure:
    default:
      return kStatusFailureString;
  }
}

void PortalDetector::CompleteAttempt(Result result) {
  LOG(INFO) << StringPrintf("Portal detection completed attempt %d with "
                            "phase==%s, status==%s, failures in content==%d",
                            attempt_count_,
                            PhaseToString(result.phase).c_str(),
                            StatusToString(result.status).c_str(),
                            failures_in_content_phase_);
  StopAttempt();

  if (result.status == kStatusFailure &&
      result.phase == kPhaseContent) {
    failures_in_content_phase_++;
  }
  if (result.status == kStatusSuccess ||
      attempt_count_ >= kMaxRequestAttempts ||
      failures_in_content_phase_ >= kMaxFailuresInContentPhase) {
    result.num_attempts = attempt_count_;
    result.final = true;
    Stop();
  } else {
    StartAttempt(0);
  }

  portal_result_callback_.Run(result);
}

PortalDetector::Result PortalDetector::GetPortalResultForRequestResult(
  HTTPRequest::Result result) {
  switch (result) {
    case HTTPRequest::kResultSuccess:
      // The request completed without receiving the expected payload.
      return Result(kPhaseContent, kStatusFailure);
    case HTTPRequest::kResultDNSFailure:
      return Result(kPhaseDNS, kStatusFailure);
    case HTTPRequest::kResultDNSTimeout:
      return Result(kPhaseDNS, kStatusTimeout);
    case HTTPRequest::kResultConnectionFailure:
      return Result(kPhaseConnection, kStatusFailure);
    case HTTPRequest::kResultConnectionTimeout:
      return Result(kPhaseConnection, kStatusTimeout);
    case HTTPRequest::kResultRequestFailure:
    case HTTPRequest::kResultResponseFailure:
      return Result(kPhaseHTTP, kStatusFailure);
    case HTTPRequest::kResultRequestTimeout:
    case HTTPRequest::kResultResponseTimeout:
      return Result(kPhaseHTTP, kStatusTimeout);
    case HTTPRequest::kResultUnknown:
    default:
      return Result(kPhaseUnknown, kStatusFailure);
  }
}

void PortalDetector::RequestReadCallback(const ByteString &response_data) {
  const string response_expected(kResponseExpected);
  bool expected_length_received = false;
  int compare_length = 0;
  if (response_data.GetLength() < response_expected.length()) {
    // There isn't enough data yet for a final decision, but we can still
    // test to see if the partial string matches so far.
    expected_length_received = false;
    compare_length = response_data.GetLength();
  } else {
    expected_length_received = true;
    compare_length = response_expected.length();
  }

  if (MatchPattern(string(reinterpret_cast<const char *>(
                              response_data.GetConstData()),
                          compare_length),
                   response_expected.substr(0, compare_length))) {
    if (expected_length_received) {
      CompleteAttempt(Result(kPhaseContent, kStatusSuccess));
    }
    // Otherwise, we wait for more data from the server.
  } else {
    CompleteAttempt(Result(kPhaseContent, kStatusFailure));
  }
}

void PortalDetector::RequestResultCallback(
    HTTPRequest::Result result, const ByteString &/*response_data*/) {
  CompleteAttempt(GetPortalResultForRequestResult(result));
}

void PortalDetector::StartAttempt(int init_delay_seconds) {
  int64 next_attempt_delay = 0;
  if (attempt_count_ > 0) {
    // Ensure that attempts are spaced at least by a minimal interval.
    struct timeval now, elapsed_time;
    time_->GetTimeMonotonic(&now);
    timersub(&now, &attempt_start_time_, &elapsed_time);

    if (elapsed_time.tv_sec < kMinTimeBetweenAttemptsSeconds) {
      struct timeval remaining_time = { kMinTimeBetweenAttemptsSeconds, 0 };
      timersub(&remaining_time, &elapsed_time, &remaining_time);
      next_attempt_delay =
        remaining_time.tv_sec * 1000 + remaining_time.tv_usec / 1000;
    }
  } else {
    next_attempt_delay = init_delay_seconds * 1000;
  }

  start_attempt_.Reset(Bind(&PortalDetector::StartAttemptTask,
                            weak_ptr_factory_.GetWeakPtr()));
  dispatcher_->PostDelayedTask(start_attempt_.callback(), next_attempt_delay);
}

void PortalDetector::StartAttemptTask() {
  time_->GetTimeMonotonic(&attempt_start_time_);
  ++attempt_count_;

  LOG(INFO) << StringPrintf("Portal detection starting attempt %d of %d",
                            attempt_count_, kMaxRequestAttempts);

  HTTPRequest::Result result =
      request_->Start(url_, request_read_callback_, request_result_callback_);
  if (result != HTTPRequest::kResultInProgress) {
    CompleteAttempt(GetPortalResultForRequestResult(result));
    return;
  }

  attempt_timeout_.Reset(Bind(&PortalDetector::TimeoutAttemptTask,
                              weak_ptr_factory_.GetWeakPtr()));
  dispatcher_->PostDelayedTask(attempt_timeout_.callback(),
                               kRequestTimeoutSeconds * 1000);
}

void PortalDetector::StopAttempt() {
  request_->Stop();
  attempt_timeout_.Cancel();
}

void PortalDetector::TimeoutAttemptTask() {
  LOG(ERROR) << "Request timed out";
  if (request_->response_data().GetLength()) {
    CompleteAttempt(Result(kPhaseContent, kStatusTimeout));
  } else {
    CompleteAttempt(Result(kPhaseUnknown, kStatusTimeout));
  }
}

}  // namespace shill
