// Copyright 2018 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/link_monitor.h"

#include <string>

#include <base/bind.h>

#include "shill/active_link_monitor.h"
#include "shill/connection.h"
#include "shill/device_info.h"
#include "shill/event_dispatcher.h"
#include "shill/logging.h"
#include "shill/net/shill_time.h"
#include "shill/passive_link_monitor.h"

using base::Bind;
using base::Unretained;
using std::string;

namespace shill {

namespace Logging {
static auto kModuleLogScope = ScopeLogger::kLink;
static string ObjectID(Connection* c) { return c->interface_name(); }
}

const int LinkMonitor::kDefaultTestPeriodMilliseconds =
    ActiveLinkMonitor::kDefaultTestPeriodMilliseconds;
const int LinkMonitor::kFailureThreshold =
    ActiveLinkMonitor::kFailureThreshold;
const char LinkMonitor::kDefaultLinkMonitorTechnologies[] = "wifi";

LinkMonitor::LinkMonitor(const ConnectionRefPtr& connection,
                         EventDispatcher* dispatcher,
                         Metrics* metrics,
                         DeviceInfo* device_info,
                         const FailureCallback& failure_callback,
                         const GatewayChangeCallback& gateway_change_callback)
    : connection_(connection),
      dispatcher_(dispatcher),
      metrics_(metrics),
      failure_callback_(failure_callback),
      gateway_change_callback_(gateway_change_callback),
      active_link_monitor_(
          new ActiveLinkMonitor(
              connection,
              dispatcher,
              metrics,
              device_info,
              Bind(&LinkMonitor::OnActiveLinkMonitorFailure,
                   Unretained(this)),
              Bind(&LinkMonitor::OnActiveLinkMonitorSuccess,
                   Unretained(this)))),
      passive_link_monitor_(
          new PassiveLinkMonitor(
              connection,
              dispatcher,
              Bind(&LinkMonitor::OnPassiveLinkMonitorResultCallback,
                   Unretained(this)))),
      time_(Time::GetInstance()) {
}

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

bool LinkMonitor::Start() {
  Stop();
  time_->GetTimeMonotonic(&started_monitoring_at_);
  // Start active link monitor.
  return active_link_monitor_->Start(
      ActiveLinkMonitor::kDefaultTestPeriodMilliseconds);
}

void LinkMonitor::Stop() {
  SLOG(connection_.get(), 2) << "In " << __func__ << ".";
  timerclear(&started_monitoring_at_);
  active_link_monitor_->Stop();
  passive_link_monitor_->Stop();
  gateway_mac_address_.Clear();
}

void LinkMonitor::OnAfterResume() {
  // Preserve gateway settings across resume.
  ByteString prior_gateway_mac_address(gateway_mac_address_);
  bool gateway_supports_unicast_arp =
      active_link_monitor_->gateway_supports_unicast_arp();
  Stop();
  gateway_mac_address_ = prior_gateway_mac_address;
  active_link_monitor_->set_gateway_mac_address(gateway_mac_address_);
  active_link_monitor_->set_gateway_supports_unicast_arp(
      gateway_supports_unicast_arp);

  active_link_monitor_->Start(ActiveLinkMonitor::kFastTestPeriodMilliseconds);
}

int LinkMonitor::GetResponseTimeMilliseconds() const {
  return active_link_monitor_->GetResponseTimeMilliseconds();
}

bool LinkMonitor::IsGatewayFound() const {
  return !gateway_mac_address_.IsZero();
}

void LinkMonitor::OnActiveLinkMonitorFailure(
    Metrics::LinkMonitorFailure failure,
    int broadcast_failure_count,
    int unicast_failure_count) {
  failure_callback_.Run();

  struct timeval now, elapsed_time;
  time_->GetTimeMonotonic(&now);
  timersub(&now, &started_monitoring_at_, &elapsed_time);

  metrics_->NotifyLinkMonitorFailure(
      connection_->technology(),
      failure,
      elapsed_time.tv_sec,
      broadcast_failure_count,
      unicast_failure_count);

  Stop();
}

void LinkMonitor::OnActiveLinkMonitorSuccess() {
  if (!gateway_mac_address_.Equals(
      active_link_monitor_->gateway_mac_address())) {
    gateway_mac_address_ = active_link_monitor_->gateway_mac_address();
    // Notify device of the new gateway mac address.
    gateway_change_callback_.Run();
  }

  // Start passive link monitoring.
  passive_link_monitor_->Start(PassiveLinkMonitor::kDefaultMonitorCycles);
}

void LinkMonitor::OnPassiveLinkMonitorResultCallback(bool status) {
  // TODO(zqiu): Add metrics for tracking passive link monitor results.

  // Start active monitor
  active_link_monitor_->Start(
      ActiveLinkMonitor::kDefaultTestPeriodMilliseconds);
}

}  // namespace shill
