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

#include <string>

#include "base/bind.h"
#include "base/sequenced_task_runner.h"
#include "base/task/post_task.h"
#include "base/task/task_traits.h"
#include "build/build_config.h"
#include "net/base/network_change_notifier_posix.h"
#include "net/dns/dns_config_service_posix.h"

#if defined(OS_ANDROID)
#include "net/android/network_change_notifier_android.h"
#endif

namespace net {

// DNS config services on Chrome OS and Android are signalled by the network
// state handler rather than relying on watching files in /etc.
class NetworkChangeNotifierPosix::DnsConfigService
    : public net::internal::DnsConfigServicePosix {
 public:
  DnsConfigService() = default;
  ~DnsConfigService() override = default;

  // net::internal::DnsConfigService() overrides.
  bool StartWatching() override {
    CreateReaders();
    // DNS config changes are handled and notified by the network
    // state handlers.
    return true;
  }

  void OnNetworkChange() {
    InvalidateConfig();
    InvalidateHosts();
    ReadNow();
  }
};

NetworkChangeNotifierPosix::NetworkChangeNotifierPosix(
    NetworkChangeNotifier::ConnectionType initial_connection_type,
    NetworkChangeNotifier::ConnectionSubtype initial_connection_subtype)
    : NetworkChangeNotifier(NetworkChangeCalculatorParamsPosix()),
      dns_config_service_runner_(
          base::CreateSequencedTaskRunnerWithTraits({base::MayBlock()})),
      dns_config_service_(
          new DnsConfigService(),
          // Ensure DnsConfigService lives on |dns_config_service_runner_|
          // to prevent races where NetworkChangeNotifierPosix outlives
          // ScopedTaskEnvironment. https://crbug.com/938126
          base::OnTaskRunnerDeleter(dns_config_service_runner_)),
      connection_type_(initial_connection_type),
      max_bandwidth_mbps_(
          NetworkChangeNotifier::GetMaxBandwidthMbpsForConnectionSubtype(
              initial_connection_subtype)) {
  dns_config_service_runner_->PostTask(
      FROM_HERE,
      base::BindOnce(
          &NetworkChangeNotifierPosix::DnsConfigService::WatchConfig,
          base::Unretained(dns_config_service_.get()),
          base::BindRepeating(&NetworkChangeNotifier::SetDnsConfig)));
  OnDNSChanged();
}

NetworkChangeNotifierPosix::~NetworkChangeNotifierPosix() = default;

void NetworkChangeNotifierPosix::OnDNSChanged() {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  dns_config_service_runner_->PostTask(
      FROM_HERE,
      base::BindOnce(
          &NetworkChangeNotifierPosix::DnsConfigService::OnNetworkChange,
          base::Unretained(dns_config_service_.get())));
}

void NetworkChangeNotifierPosix::OnIPAddressChanged() {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  NetworkChangeNotifier::NotifyObserversOfIPAddressChange();
}

void NetworkChangeNotifierPosix::OnConnectionChanged(
    NetworkChangeNotifier::ConnectionType connection_type) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  {
    base::AutoLock scoped_lock(lock_);
    connection_type_ = connection_type;
  }
  NetworkChangeNotifier::NotifyObserversOfConnectionTypeChange();
}

void NetworkChangeNotifierPosix::OnConnectionSubtypeChanged(
    NetworkChangeNotifier::ConnectionType connection_type,
    NetworkChangeNotifier::ConnectionSubtype connection_subtype) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  double max_bandwidth_mbps =
      GetMaxBandwidthMbpsForConnectionSubtype(connection_subtype);
  {
    base::AutoLock scoped_lock(lock_);
    max_bandwidth_mbps_ = max_bandwidth_mbps;
  }
  NetworkChangeNotifier::NotifyObserversOfMaxBandwidthChange(max_bandwidth_mbps,
                                                             connection_type);
}

NetworkChangeNotifier::ConnectionType
NetworkChangeNotifierPosix::GetCurrentConnectionType() const {
  base::AutoLock scoped_lock(lock_);
  return connection_type_;
}

void NetworkChangeNotifierPosix::GetCurrentMaxBandwidthAndConnectionType(
    double* max_bandwidth_mbps,
    ConnectionType* connection_type) const {
  base::AutoLock scoped_lock(lock_);
  *connection_type = connection_type_;
  *max_bandwidth_mbps = max_bandwidth_mbps_;
}

// static
NetworkChangeNotifier::NetworkChangeCalculatorParams
NetworkChangeNotifierPosix::NetworkChangeCalculatorParamsPosix() {
  NetworkChangeCalculatorParams params;
#if defined(OS_CHROMEOS)
  // Delay values arrived at by simple experimentation and adjusted so as to
  // produce a single signal when switching between network connections.
  params.ip_address_offline_delay_ = base::TimeDelta::FromMilliseconds(4000);
  params.ip_address_online_delay_ = base::TimeDelta::FromMilliseconds(1000);
  params.connection_type_offline_delay_ =
      base::TimeDelta::FromMilliseconds(500);
  params.connection_type_online_delay_ = base::TimeDelta::FromMilliseconds(500);
#elif defined(OS_ANDROID)
  params =
      net::NetworkChangeNotifierAndroid::NetworkChangeCalculatorParamsAndroid();
#else
  NOTIMPLEMENTED();
#endif
  return params;
}

}  // namespace net
