// 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 "content/browser/geolocation/wifi_data_provider_common.h"

#include "base/bind.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"

namespace content {

base::string16 MacAddressAsString16(const uint8 mac_as_int[6]) {
  // mac_as_int is big-endian. Write in byte chunks.
  // Format is XX-XX-XX-XX-XX-XX.
  static const char* const kMacFormatString =
      "%02x-%02x-%02x-%02x-%02x-%02x";
  return base::ASCIIToUTF16(base::StringPrintf(kMacFormatString,
                                               mac_as_int[0],
                                               mac_as_int[1],
                                               mac_as_int[2],
                                               mac_as_int[3],
                                               mac_as_int[4],
                                               mac_as_int[5]));
}

WifiDataProviderCommon::WifiDataProviderCommon()
    : is_first_scan_complete_(false),
      weak_factory_(this) {
}

WifiDataProviderCommon::~WifiDataProviderCommon() {
}

void WifiDataProviderCommon::StartDataProvider() {
  DCHECK(wlan_api_ == NULL);
  wlan_api_.reset(NewWlanApi());
  if (wlan_api_ == NULL) {
    // Error! Can't do scans, so don't try and schedule one.
    is_first_scan_complete_ = true;
    return;
  }

  DCHECK(polling_policy_ == NULL);
  polling_policy_.reset(NewPollingPolicy());
  DCHECK(polling_policy_ != NULL);

  // Perform first scan ASAP regardless of the polling policy. If this scan
  // fails we'll retry at a rate in line with the polling policy.
  ScheduleNextScan(0);
}

void WifiDataProviderCommon::StopDataProvider() {
  wlan_api_.reset();
  polling_policy_.reset();
}

bool WifiDataProviderCommon::GetData(WifiData* data) {
  *data = wifi_data_;
  // If we've successfully completed a scan, indicate that we have all of the
  // data we can get.
  return is_first_scan_complete_;
}

void WifiDataProviderCommon::DoWifiScanTask() {
  bool update_available = false;
  WifiData new_data;
  if (!wlan_api_->GetAccessPointData(&new_data.access_point_data)) {
    ScheduleNextScan(polling_policy_->NoWifiInterval());
  } else {
    update_available = wifi_data_.DiffersSignificantly(new_data);
    wifi_data_ = new_data;
    polling_policy_->UpdatePollingInterval(update_available);
    ScheduleNextScan(polling_policy_->PollingInterval());
  }
  if (update_available || !is_first_scan_complete_) {
    is_first_scan_complete_ = true;
    RunCallbacks();
  }
}

void WifiDataProviderCommon::ScheduleNextScan(int interval) {
  client_loop()->PostDelayedTask(
      FROM_HERE,
      base::Bind(&WifiDataProviderCommon::DoWifiScanTask,
                 weak_factory_.GetWeakPtr()),
      base::TimeDelta::FromMilliseconds(interval));
}

}  // namespace content
