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

#include "chromecast/net/connectivity_checker_impl.h"

#include "base/bind.h"
#include "base/command_line.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/values.h"
#include "chromecast/base/metrics/cast_metrics_helper.h"
#include "chromecast/chromecast_buildflags.h"
#include "chromecast/net/net_switches.h"
#include "chromecast/net/time_sync_tracker.h"
#include "net/base/request_priority.h"
#include "net/http/http_network_session.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_response_info.h"
#include "net/http/http_status_code.h"
#include "net/http/http_transaction_factory.h"
#include "net/socket/ssl_client_socket.h"
#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/cpp/simple_url_loader.h"
#include "services/network/public/mojom/network_change_manager.mojom.h"

namespace chromecast {

namespace {

// How often connectivity checks are performed in seconds while not connected.
const unsigned int kConnectivityPeriodSeconds = 1;

// How often connectivity checks are performed in seconds while connected.
const unsigned int kConnectivitySuccessPeriodSeconds = 60;

// Number of consecutive connectivity check errors before status is changed
// to offline.
const unsigned int kNumErrorsToNotifyOffline = 3;

// Request timeout value in seconds.
const unsigned int kRequestTimeoutInSeconds = 3;

// Delay notification of network change events to smooth out rapid flipping.
// Histogram "Cast.Network.Down.Duration.In.Seconds" shows 40% of network
// downtime is less than 3 seconds.
const char kNetworkChangedDelayInSeconds = 3;

const char kMetricNameNetworkConnectivityCheckingErrorType[] =
    "Network.ConnectivityChecking.ErrorType";

}  // namespace

// static
scoped_refptr<ConnectivityCheckerImpl> ConnectivityCheckerImpl::Create(
    scoped_refptr<base::SingleThreadTaskRunner> task_runner,
    std::unique_ptr<network::PendingSharedURLLoaderFactory>
        pending_url_loader_factory,
    network::NetworkConnectionTracker* network_connection_tracker,
    TimeSyncTracker* time_sync_tracker) {
  DCHECK(task_runner);

  auto connectivity_checker = base::WrapRefCounted(new ConnectivityCheckerImpl(
      task_runner, network_connection_tracker, time_sync_tracker));
  task_runner->PostTask(
      FROM_HERE,
      base::BindOnce(&ConnectivityCheckerImpl::Initialize, connectivity_checker,
                     std::move(pending_url_loader_factory)));
  return connectivity_checker;
}

ConnectivityCheckerImpl::ConnectivityCheckerImpl(
    scoped_refptr<base::SingleThreadTaskRunner> task_runner,
    network::NetworkConnectionTracker* network_connection_tracker,
    TimeSyncTracker* time_sync_tracker)
    : ConnectivityChecker(task_runner),
      task_runner_(std::move(task_runner)),
      network_connection_tracker_(network_connection_tracker),
      time_sync_tracker_(time_sync_tracker),
      cast_metrics_helper_(metrics::CastMetricsHelper::GetInstance()),
      connected_and_time_synced_(false),
      network_connected_(false),
      connection_type_(network::mojom::ConnectionType::CONNECTION_NONE),
      check_errors_(0),
      network_changed_pending_(false),
      weak_factory_(this) {
  DCHECK(task_runner_);
  DCHECK(network_connection_tracker_);
  DCHECK(cast_metrics_helper_);
  weak_this_ = weak_factory_.GetWeakPtr();

  if (time_sync_tracker_) {
    time_sync_tracker_->AddObserver(this);
  }
}

void ConnectivityCheckerImpl::Initialize(
    std::unique_ptr<network::PendingSharedURLLoaderFactory>
        pending_url_loader_factory) {
  DCHECK(task_runner_->BelongsToCurrentThread());
  DCHECK(pending_url_loader_factory);
  url_loader_factory_ = network::SharedURLLoaderFactory::Create(
      std::move(pending_url_loader_factory));

  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  base::CommandLine::StringType check_url_str =
      command_line->GetSwitchValueNative(switches::kConnectivityCheckUrl);
  connectivity_check_url_ = std::make_unique<GURL>(
      check_url_str.empty() ? kDefaultConnectivityCheckUrl : check_url_str);

  network_connection_tracker_->AddNetworkConnectionObserver(this);

  Check();
}

ConnectivityCheckerImpl::~ConnectivityCheckerImpl() {
  DCHECK(task_runner_);
  DCHECK(task_runner_->BelongsToCurrentThread());
  network_connection_tracker_->RemoveNetworkConnectionObserver(this);
}

bool ConnectivityCheckerImpl::Connected() const {
  base::AutoLock auto_lock(connected_lock_);
  return connected_and_time_synced_;
}

void ConnectivityCheckerImpl::SetConnected(bool connected) {
  DCHECK(task_runner_->BelongsToCurrentThread());
  {
    base::AutoLock auto_lock(connected_lock_);
    network_connected_ = connected;

    // If a time_sync_tracker is not provided, is it assumed that network
    // connectivity is equivalent to time being synced.
    bool connected_and_time_synced = network_connected_;
    if (time_sync_tracker_) {
      connected_and_time_synced &= time_sync_tracker_->IsTimeSynced();
    }

    if (connected_and_time_synced_ == connected_and_time_synced) {
      return;
    }

    connected_and_time_synced_ = connected_and_time_synced;
  }

  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  base::CommandLine::StringType check_url_str =
      command_line->GetSwitchValueNative(switches::kConnectivityCheckUrl);
  if (check_url_str.empty()) {
    connectivity_check_url_ = std::make_unique<GURL>(
        connected_and_time_synced_ ? kHttpConnectivityCheckUrl
                                   : kDefaultConnectivityCheckUrl);
    LOG(INFO) << "Change check url=" << *connectivity_check_url_;
  }

  Notify(connected_and_time_synced_);
  LOG(INFO) << "Global connection is: "
            << (connected_and_time_synced_ ? "Up" : "Down");
}

void ConnectivityCheckerImpl::Check() {
  task_runner_->PostTask(
      FROM_HERE,
      base::BindOnce(&ConnectivityCheckerImpl::CheckInternal, weak_this_));
}

void ConnectivityCheckerImpl::CheckInternal() {
  DCHECK(task_runner_->BelongsToCurrentThread());
  DCHECK(url_loader_factory_);

  auto connection_type = network::mojom::ConnectionType::CONNECTION_UNKNOWN;
  bool is_sync = network_connection_tracker_->GetConnectionType(
      &connection_type,
      base::BindOnce(&ConnectivityCheckerImpl::OnConnectionChanged,
                     weak_this_));

  // Don't check connectivity if network is offline.
  // Also don't check connectivity if the connection_type cannot be
  // synchronously retrieved, since OnConnectionChanged will be triggered later
  // which will cause duplicate checks.
  if (!is_sync ||
      connection_type == network::mojom::ConnectionType::CONNECTION_NONE) {
    return;
  }

  // If url_loader_ is non-null, there is already a check going on. Don't
  // start another.
  if (url_loader_) {
    return;
  }

  VLOG(1) << "Connectivity check: url=" << *connectivity_check_url_;
  auto resource_request = std::make_unique<network::ResourceRequest>();
  resource_request->url = GURL(*connectivity_check_url_);
  resource_request->method = "HEAD";
  resource_request->priority = net::MAXIMUM_PRIORITY;
  // To enable ssl_info in the response.
  resource_request->report_raw_headers = true;

  url_loader_ = network::SimpleURLLoader::Create(std::move(resource_request),
                                                 MISSING_TRAFFIC_ANNOTATION);

  // Configure the loader to treat HTTP error status codes as successful loads.
  // This setting allows us to inspect the status code and log it as an error.
  url_loader_->SetAllowHttpErrorResults(true);

  network::SimpleURLLoader::HeadersOnlyCallback callback = base::BindOnce(
      &ConnectivityCheckerImpl::OnConnectivityCheckComplete, weak_this_);
  url_loader_->DownloadHeadersOnly(url_loader_factory_.get(),
                                   std::move(callback));

  timeout_.Reset(base::BindOnce(&ConnectivityCheckerImpl::OnUrlRequestTimeout,
                                weak_this_));
  // Exponential backoff for timeout in 3, 6 and 12 sec.
  const int timeout = kRequestTimeoutInSeconds
                      << (check_errors_ > 2 ? 2 : check_errors_);
  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE, timeout_.callback(), base::TimeDelta::FromSeconds(timeout));
}

void ConnectivityCheckerImpl::SetCastMetricsHelperForTesting(
    metrics::CastMetricsHelper* cast_metrics_helper) {
  DCHECK(cast_metrics_helper);
  cast_metrics_helper_ = cast_metrics_helper;
}

void ConnectivityCheckerImpl::OnConnectionChanged(
    network::mojom::ConnectionType type) {
  DVLOG(2) << "OnConnectionChanged " << type;
  connection_type_ = type;

  if (network_changed_pending_)
    return;
  network_changed_pending_ = true;
  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE,
      base::BindOnce(&ConnectivityCheckerImpl::OnConnectionChangedInternal,
                     weak_this_),
      base::TimeDelta::FromSeconds(kNetworkChangedDelayInSeconds));
}

void ConnectivityCheckerImpl::OnConnectionChangedInternal() {
  network_changed_pending_ = false;
  Cancel();

  if (connection_type_ == network::mojom::ConnectionType::CONNECTION_NONE) {
    SetConnected(false);
    return;
  }

  Check();
}

void ConnectivityCheckerImpl::OnTimeSynced() {
  SetConnected(network_connected_);
}

void ConnectivityCheckerImpl::OnConnectivityCheckComplete(
    scoped_refptr<net::HttpResponseHeaders> headers) {
  DCHECK(task_runner_->BelongsToCurrentThread());
  DCHECK(url_loader_);

  // Move url_loader_ onto the stack to ensure it gets deleted when this
  // function completes.
  std::unique_ptr<network::SimpleURLLoader> url_loader = std::move(url_loader_);

  timeout_.Cancel();
  int error = url_loader->NetError();
  if (error == net::ERR_INSECURE_RESPONSE && url_loader->ResponseInfo() &&
      url_loader->ResponseInfo()->ssl_info) {
    LOG(ERROR) << "OnSSLCertificateError: cert_status="
               << url_loader->ResponseInfo()->ssl_info->cert_status;
    OnUrlRequestError(ErrorType::SSL_CERTIFICATE_ERROR);
    return;
  }
  if (error != net::OK) {
    // Captures non-HTTP errors here. All HTTP status codes (including error
    // codes) are treated as network success and won't be logged here. HTTP
    // errors are handled further below to provide more precise granularity.
    LOG(ERROR) << "Connectivity check failed: net_error=" << error;
    OnUrlRequestError(ErrorType::NET_ERROR);
    return;
  }

  // At this point, network connection is considered successful, but we still
  // need to check HTTP response for errors. If headers are empty, use an
  // implicit zero status code.
  int http_response_code = headers ? headers->response_code() : 0;

  if (http_response_code != kConnectivitySuccessStatusCode) {
    LOG(ERROR) << "Connectivity check failed: http_response_code="
               << http_response_code;
    OnUrlRequestError(ErrorType::BAD_HTTP_STATUS);
    return;
  }

  DVLOG(1) << "Connectivity check succeeded";
  check_errors_ = 0;
  SetConnected(true);
  if (time_sync_tracker_) {
    time_sync_tracker_->OnNetworkConnected();
  }
  // Some products don't have an idle screen that makes periodic network
  // requests. Schedule another check to ensure connectivity hasn't dropped.
  task_runner_->PostDelayedTask(
      FROM_HERE,
      base::BindOnce(&ConnectivityCheckerImpl::CheckInternal, weak_this_),
      base::TimeDelta::FromSeconds(kConnectivitySuccessPeriodSeconds));
}

void ConnectivityCheckerImpl::OnUrlRequestError(ErrorType type) {
  DCHECK(task_runner_->BelongsToCurrentThread());
  ++check_errors_;
  if (check_errors_ > kNumErrorsToNotifyOffline) {
    // Only record event on the connectivity transition.
    if (connected_and_time_synced_) {
      cast_metrics_helper_->RecordEventWithValue(
          kMetricNameNetworkConnectivityCheckingErrorType,
          static_cast<int>(type));
    }
    check_errors_ = kNumErrorsToNotifyOffline;
    SetConnected(false);
  }
  // Check again.
  task_runner_->PostDelayedTask(
      FROM_HERE, base::BindOnce(&ConnectivityCheckerImpl::Check, weak_this_),
      base::TimeDelta::FromSeconds(kConnectivityPeriodSeconds));
}

void ConnectivityCheckerImpl::OnUrlRequestTimeout() {
  DCHECK(task_runner_->BelongsToCurrentThread());
  DCHECK(url_loader_);
  url_loader_ = nullptr;
  LOG(ERROR) << "time out";
  OnUrlRequestError(ErrorType::REQUEST_TIMEOUT);
}

void ConnectivityCheckerImpl::Cancel() {
  DCHECK(task_runner_->BelongsToCurrentThread());
  if (!url_loader_)
    return;
  VLOG(2) << "Cancel connectivity check in progress";
  url_loader_ = nullptr;
  timeout_.Cancel();
}

}  // namespace chromecast
