// Copyright (c) 2013 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/scan_session.h"

#include <algorithm>
#include <set>
#include <string>
#include <vector>

#include <base/bind.h>
#include <base/memory/weak_ptr.h>
#include <base/stl_util.h>
#include <base/strings/stringprintf.h>

#include "shill/event_dispatcher.h"
#include "shill/logging.h"
#include "shill/metrics.h"
#include "shill/netlink_manager.h"
#include "shill/nl80211_attribute.h"
#include "shill/nl80211_message.h"

using base::Bind;
using base::StringPrintf;
using std::set;
using std::string;
using std::vector;

namespace shill {

const float ScanSession::kAllFrequencies = 1.1;
const uint64_t ScanSession::kScanRetryDelayMilliseconds = 200;  // Arbitrary.
const size_t ScanSession::kScanRetryCount = 50;

ScanSession::ScanSession(
    NetlinkManager *netlink_manager,
    EventDispatcher *dispatcher,
    const WiFiProvider::FrequencyCountList &previous_frequencies,
    const set<uint16_t> &available_frequencies,
    uint32_t ifindex,
    const FractionList &fractions,
    size_t min_frequencies,
    size_t max_frequencies,
    OnScanFailed on_scan_failed,
    Metrics *metrics)
    : weak_ptr_factory_(this),
      netlink_manager_(netlink_manager),
      dispatcher_(dispatcher),
      frequency_list_(previous_frequencies),
      total_connections_(0),
      total_connects_provided_(0),
      total_fraction_wanted_(0.0),
      wifi_interface_index_(ifindex),
      ssids_(ByteString::IsLessThan),
      fractions_(fractions),
      min_frequencies_(min_frequencies),
      max_frequencies_(max_frequencies),
      on_scan_failed_(on_scan_failed),
      scan_tries_left_(kScanRetryCount),
      found_error_(false),
      metrics_(metrics) {
  sort(frequency_list_.begin(), frequency_list_.end(),
       &ScanSession::CompareFrequencyCount);
  // Add to |frequency_list_| all the frequencies from |available_frequencies|
  // that aren't in |previous_frequencies|.
  set<uint16_t> seen_frequencies;
  for (const auto &freq_conn : frequency_list_) {
    seen_frequencies.insert(freq_conn.frequency);
    total_connections_ += freq_conn.connection_count;
  }
  for (const auto freq : available_frequencies) {
    if (!ContainsKey(seen_frequencies, freq)) {
      frequency_list_.push_back(WiFiProvider::FrequencyCount(freq, 0));
    }
  }

  SLOG(WiFi, 6) << "Frequency connections vector:";
  for (const auto &freq_conn : frequency_list_) {
    SLOG(WiFi, 6) << "    freq[" << freq_conn.frequency << "] = "
                  << freq_conn.connection_count;
  }

  original_frequency_count_ = frequency_list_.size();
  ebusy_timer_.Pause();
}

ScanSession::~ScanSession() {
  const int kLogLevel = 6;
  ReportResults(kLogLevel);
}

bool ScanSession::HasMoreFrequencies() const {
  return !frequency_list_.empty();
}

vector<uint16_t> ScanSession::GetScanFrequencies(float fraction_wanted,
                                                 size_t min_frequencies,
                                                 size_t max_frequencies) {
  DCHECK_GE(fraction_wanted, 0);
  total_fraction_wanted_ += fraction_wanted;
  float total_connects_wanted = total_fraction_wanted_ * total_connections_;

  vector<uint16_t> frequencies;
  WiFiProvider::FrequencyCountList::iterator freq_connect =
      frequency_list_.begin();
  SLOG(WiFi, 7) << "Scanning for frequencies:";
  while (freq_connect != frequency_list_.end()) {
    if (frequencies.size() >= min_frequencies) {
      if (total_connects_provided_ >= total_connects_wanted)
        break;
      if (frequencies.size() >= max_frequencies)
        break;
    }
    uint16_t frequency = freq_connect->frequency;
    size_t connection_count = freq_connect->connection_count;
    total_connects_provided_ += connection_count;
    frequencies.push_back(frequency);
    SLOG(WiFi, 7) << "    freq[" << frequency << "] = " << connection_count;

    freq_connect = frequency_list_.erase(freq_connect);
  }
  return frequencies;
}

void ScanSession::InitiateScan() {
  float fraction_wanted = kAllFrequencies;
  if (!fractions_.empty()) {
    fraction_wanted = fractions_.front();
    fractions_.pop_front();
  }
  current_scan_frequencies_ = GetScanFrequencies(fraction_wanted,
                                                 min_frequencies_,
                                                 max_frequencies_);
  DoScan(current_scan_frequencies_);
}

void ScanSession::ReInitiateScan() {
  ebusy_timer_.Pause();
  DoScan(current_scan_frequencies_);
}

void ScanSession::DoScan(const vector<uint16_t> &scan_frequencies) {
  if (scan_frequencies.empty()) {
    LOG(INFO) << "Not sending empty frequency list";
    return;
  }
  TriggerScanMessage trigger_scan;
  trigger_scan.attributes()->SetU32AttributeValue(NL80211_ATTR_IFINDEX,
                                                  wifi_interface_index_);
  AttributeListRefPtr frequency_list;
  if (!trigger_scan.attributes()->GetNestedAttributeList(
      NL80211_ATTR_SCAN_FREQUENCIES, &frequency_list) || !frequency_list) {
    LOG(FATAL) << "Couldn't get NL80211_ATTR_SCAN_FREQUENCIES.";
  }
  trigger_scan.attributes()->SetNestedAttributeHasAValue(
      NL80211_ATTR_SCAN_FREQUENCIES);

  SLOG(WiFi, 6) << "We have requested scan frequencies:";
  string attribute_name;
  int i = 0;
  for (const auto freq : scan_frequencies) {
    SLOG(WiFi, 6) << "  " << freq;
    attribute_name = StringPrintf("Frequency-%d", i);
    frequency_list->CreateU32Attribute(i, attribute_name.c_str());
    frequency_list->SetU32AttributeValue(i, freq);
    ++i;
  }

  if (!ssids_.empty()) {
    AttributeListRefPtr ssid_list;
    if (!trigger_scan.attributes()->GetNestedAttributeList(
        NL80211_ATTR_SCAN_SSIDS, &ssid_list) || !ssid_list) {
      LOG(FATAL) << "Couldn't get NL80211_ATTR_SCAN_SSIDS attribute.";
    }
    trigger_scan.attributes()->SetNestedAttributeHasAValue(
        NL80211_ATTR_SCAN_SSIDS);
    int i = 0;
    string attribute_name;
    for (const auto &ssid : ssids_) {
      attribute_name = StringPrintf("NL80211_ATTR_SSID_%d", i);
      ssid_list->CreateRawAttribute(i, attribute_name.c_str());
      ssid_list->SetRawAttributeValue(i, ssid);
      ++i;
    }
    // Add an empty one at the end so we ask for a broadcast in addition to
    // the specific SSIDs.
    attribute_name = StringPrintf("NL80211_ATTR_SSID_%d", i);
    ssid_list->CreateRawAttribute(i, attribute_name.c_str());
    ssid_list->SetRawAttributeValue(i, ByteString());
  }
  netlink_manager_->SendNl80211Message(
      &trigger_scan,
      Bind(&ScanSession::OnTriggerScanResponse,
           weak_ptr_factory_.GetWeakPtr()),
      Bind(&NetlinkManager::OnAckDoNothing),
      Bind(&ScanSession::OnTriggerScanErrorResponse,
           weak_ptr_factory_.GetWeakPtr()));
}

void ScanSession::OnTriggerScanResponse(const Nl80211Message &netlink_message) {
  LOG(WARNING) << "Didn't expect _this_ netlink message, here:";
  netlink_message.Print(0, 0);
  on_scan_failed_.Run();
  return;
}

void ScanSession::OnTriggerScanErrorResponse(
    NetlinkManager::AuxilliaryMessageType type,
    const NetlinkMessage *netlink_message) {
  switch (type) {
    case NetlinkManager::kErrorFromKernel: {
        if (!netlink_message) {
          LOG(ERROR) << __func__ << ": Message failed: NetlinkManager Error.";
          found_error_ = true;
          on_scan_failed_.Run();
          break;
        }
        if (netlink_message->message_type() !=
            ErrorAckMessage::GetMessageType()) {
          LOG(ERROR) << __func__ << ": Message failed: Not an error.";
          found_error_ = true;
          on_scan_failed_.Run();
          break;
        }
        const ErrorAckMessage *error_ack_message =
            dynamic_cast<const ErrorAckMessage *>(netlink_message);
        if (error_ack_message->error()) {
          LOG(ERROR) << __func__ << ": Message failed: "
                     << error_ack_message->ToString();
          if (error_ack_message->error() == EBUSY) {
            if (scan_tries_left_ == 0) {
              LOG(ERROR) << "Retried progressive scan " << kScanRetryCount
                         << " times and failed each time.  Giving up.";
              found_error_ = true;
              on_scan_failed_.Run();
              scan_tries_left_ = kScanRetryCount;
              return;
            }
            --scan_tries_left_;
            SLOG(WiFi, 3) << __func__ << " - trying again (" << scan_tries_left_
                          << " remaining after this)";
            ebusy_timer_.Resume();
            dispatcher_->PostDelayedTask(Bind(&ScanSession::ReInitiateScan,
                                              weak_ptr_factory_.GetWeakPtr()),
                                         kScanRetryDelayMilliseconds);
            break;
          }
          found_error_ = true;
          on_scan_failed_.Run();
        } else {
          SLOG(WiFi, 6) << __func__ << ": Message ACKed";
        }
      }
      break;

    case NetlinkManager::kUnexpectedResponseType:
      LOG(ERROR) << "Message not handled by regular message handler:";
      if (netlink_message) {
        netlink_message->Print(0, 0);
      }
      found_error_ = true;
      on_scan_failed_.Run();
      break;

    case NetlinkManager::kTimeoutWaitingForResponse:
      // This is actually expected since, in the working case, a trigger scan
      // message gets its responses broadcast rather than unicast.
      break;

    default:
      LOG(ERROR) << "Unexpected auxiliary message type: " << type;
      found_error_ = true;
      on_scan_failed_.Run();
      break;
  }
}

void ScanSession::ReportResults(int log_level) {
  SLOG(WiFi, log_level) << "------ ScanSession finished ------";
  SLOG(WiFi, log_level) << "Scanned "
                        << original_frequency_count_ - frequency_list_.size()
                        << " frequencies (" << frequency_list_.size()
                        << " remaining)";
  if (found_error_) {
    SLOG(WiFi, log_level) << "ERROR encountered during scan ("
                          << current_scan_frequencies_.size() << " frequencies"
                          << " dangling - counted as scanned but, really, not)";
  } else {
    SLOG(WiFi, log_level) << "No error encountered during scan.";
  }

  base::TimeDelta elapsed_time;
  ebusy_timer_.GetElapsedTime(&elapsed_time);
  if (metrics_) {
    metrics_->SendToUMA(Metrics::kMetricWiFiScanTimeInEbusyMilliseconds,
                        elapsed_time.InMilliseconds(),
                        Metrics::kMetricTimeToScanMillisecondsMin,
                        Metrics::kMetricTimeToScanMillisecondsMax,
                        Metrics::kMetricTimeToScanMillisecondsNumBuckets);
  }
  SLOG(WiFi, log_level) << "Spent " << elapsed_time.InMillisecondsRoundedUp()
                        << " milliseconds waiting for EBUSY.";
}

void ScanSession::AddSsid(const ByteString &ssid) {
  ssids_.insert(ssid);
}

// static
bool ScanSession::CompareFrequencyCount(
    const WiFiProvider::FrequencyCount &first,
    const WiFiProvider::FrequencyCount &second) {
  return first.connection_count > second.connection_count;
}

}  // namespace shill

