// Copyright 2017 The Fuchsia 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 <wlan/mlme/client/scanner.h>

#include <wlan/common/logging.h>
#include <wlan/mlme/device_interface.h>
#include <wlan/mlme/mac_frame.h>
#include <wlan/mlme/packet.h>
#include <wlan/mlme/sequence.h>
#include <wlan/mlme/service.h>
#include <wlan/mlme/timer.h>
#include <wlan/mlme/wlan.h>

#include <fuchsia/wlan/mlme/c/fidl.h>
#include "lib/fidl/cpp/vector.h"

#include <fbl/unique_ptr.h>
#include <lib/fxl/arraysize.h>
#include <lib/zx/time.h>
#include <zircon/assert.h>
#include <zircon/status.h>

#include <cinttypes>
#include <utility>

namespace wlan {

namespace wlan_mlme = ::fuchsia::wlan::mlme;

static constexpr size_t kMaxBss = 1000;

static void SendScanEnd(DeviceInterface* device, uint64_t txn_id, wlan_mlme::ScanResultCodes code) {
    wlan_mlme::ScanEnd msg;
    msg.txn_id = txn_id;
    msg.code = code;
    zx_status_t s = SendServiceMsg(device, &msg, fuchsia_wlan_mlme_MLMEOnScanEndOrdinal);
    if (s != ZX_OK) { errorf("failed to send OnScanEnd event: %d\n", s); }
}

static zx_status_t SendResults(DeviceInterface* device, uint64_t txn_id,
                               const std::unordered_map<uint64_t, Bss>& bss_map) {
    for (auto& p : bss_map) {
        wlan_mlme::ScanResult r;
        r.txn_id = txn_id;
        if (p.second.bss_desc().Clone(&r.bss) != ZX_OK) { continue; }
        zx_status_t status = SendServiceMsg(device, &r, fuchsia_wlan_mlme_MLMEOnScanResultOrdinal);
        if (status != ZX_OK) { return status; }
    }
    return ZX_OK;
}

// TODO(NET-500): The way we handle Beacons and ProbeResponses in here is kinda gross. Refactor.

Scanner::Scanner(DeviceInterface* device, ChannelScheduler* chan_sched)
    : off_channel_handler_(this), device_(device), chan_sched_(chan_sched) {}

zx_status_t Scanner::HandleMlmeScanReq(const MlmeMsg<wlan_mlme::ScanRequest>& req) {
    return Start(req);
}

zx_status_t Scanner::Start(const MlmeMsg<wlan_mlme::ScanRequest>& req) {
    debugfn();

    if (IsRunning()) {
        SendScanEnd(device_, req.body()->txn_id, wlan_mlme::ScanResultCodes::NOT_SUPPORTED);
        return ZX_ERR_UNAVAILABLE;
    }

    if (req.body()->channel_list->size() == 0 ||
        req.body()->max_channel_time < req.body()->min_channel_time) {
        SendScanEnd(device_, req.body()->txn_id, wlan_mlme::ScanResultCodes::INVALID_ARGS);
        return ZX_ERR_INVALID_ARGS;
    }
    // TODO(NET-629): re-enable checking the enum value after fidl2 lands
    // if (!BSSTypes_IsValidValue(req.body()->bss_type) ||
    // !ScanTypes_IsValidValue(req.body()->scan_type)) {
    //    return SendScanConfirm();
    //}

    req_ = wlan_mlme::ScanRequest::New();
    zx_status_t status = req.body()->Clone(req_.get());
    if (status != ZX_OK) {
        errorf("could not clone Scanrequest: %d\n", status);
        SendScanEnd(device_, req.body()->txn_id, wlan_mlme::ScanResultCodes::INTERNAL_ERROR);
        Reset();
        return status;
    }

    if (device_->GetWlanInfo().ifc_info.driver_features & WLAN_DRIVER_FEATURE_SCAN_OFFLOAD) {
        debugscan("starting a hardware scan\n");
        return StartHwScan();
    } else {
        debugscan("starting a software scan\n");
        ZX_DEBUG_ASSERT(channel_index_ == 0);
        chan_sched_->RequestOffChannelTime(CreateOffChannelRequest());
        return ZX_OK;
    }
}

zx_status_t Scanner::StartHwScan() {
    wlan_hw_scan_config_t config = {};
    const auto& chans = req_->channel_list;
    if (chans->size() > arraysize(config.channels)) {
        errorf("too many channels to scan: %zu\n", chans->size());
        SendScanEnd(device_, req_->txn_id, wlan_mlme::ScanResultCodes::INVALID_ARGS);
        Reset();
        return ZX_ERR_INVALID_ARGS;
    }
    config.num_channels = chans->size();
    std::copy(chans->begin(), chans->end(), config.channels);

    zx_status_t status = device_->StartHwScan(&config);
    if (status != ZX_OK) {
        errorf("StartHwScan returned an error: %s\n", zx_status_get_string(status));
        SendScanEnd(device_, req_->txn_id, wlan_mlme::ScanResultCodes::INTERNAL_ERROR);
        Reset();
        return status;
    }
    return ZX_OK;
}

void Scanner::OffChannelHandlerImpl::BeginOffChannelTime() {
    // Don't do anything for now. For active scans, we should send a probe request,
    // or set a timer to send a probe request.
    // TODO(NET-1294)
}

void Scanner::OffChannelHandlerImpl::HandleOffChannelFrame(fbl::unique_ptr<Packet> pkt) {
    if (auto mgmt_frame = MgmtFrameView<>::CheckType(pkt.get()).CheckLength()) {
        if (auto bcn_frame = mgmt_frame.CheckBodyType<Beacon>().CheckLength()) {
            scanner_->HandleBeacon(bcn_frame);
        }
    }
}

bool Scanner::OffChannelHandlerImpl::EndOffChannelTime(bool interrupted,
                                                       OffChannelRequest* next_req) {
    // If we were interrupted before the timeout ended, scan the channel again
    if (interrupted) {
        *next_req = scanner_->CreateOffChannelRequest();
        return true;
    }

    scanner_->channel_index_ += 1;
    if (scanner_->channel_index_ >= scanner_->req_->channel_list->size()) {
        scanner_->SendResultsAndReset();
        return false;
    }

    *next_req = scanner_->CreateOffChannelRequest();
    return true;
}

void Scanner::Reset() {
    debugfn();
    req_.reset();
    channel_index_ = 0;
    current_bss_.clear();
}

bool Scanner::IsRunning() const {
    return req_ != nullptr;
}

wlan_channel_t Scanner::ScanChannel() const {
    debugfn();
    ZX_DEBUG_ASSERT(IsRunning());
    ZX_DEBUG_ASSERT(channel_index_ < req_->channel_list->size());
    return wlan_channel_t{
        .primary = req_->channel_list->at(channel_index_),
    };
}

bool Scanner::ShouldDropMgmtFrame(const MgmtFrameHeader& hdr) {
    // Ignore all management frames when scanner is not running.
    if (!IsRunning()) { return true; }

    common::MacAddr bssid(hdr.addr3);
    common::MacAddr src_addr(hdr.addr2);
    if (bssid != src_addr) {
        // Undefined situation. Investigate if roaming needs this or this is a plain dark art.
        // Do not process frame.
        debugbcn("Rxed a beacon/probe_resp from the non-BSSID station: BSSID %s   SrcAddr %s\n",
                 MACSTR(bssid), MACSTR(src_addr));
        return true;
    }

    return false;
}

void Scanner::HandleBeacon(const MgmtFrameView<Beacon>& frame) {
    debugfn();
    if (!ShouldDropMgmtFrame(*frame.hdr())) { ProcessBeacon(frame); }
}

void Scanner::ProcessBeacon(const MgmtFrameView<Beacon>& mgmt_bcn_frame) {
    debugfn();
    auto bssid = mgmt_bcn_frame.hdr()->addr3;

    auto it = current_bss_.find(bssid.ToU64());
    if (it == current_bss_.end()) {
        if (current_bss_.size() >= kMaxBss) {
            errorf("maximum number of BSS reached: %lu\n", current_bss_.size());
            return;
        }
        it = current_bss_
                 .emplace(std::piecewise_construct, std::forward_as_tuple(bssid.ToU64()),
                          std::forward_as_tuple(bssid))
                 .first;
    }

    auto rx_info = mgmt_bcn_frame.rx_info();
    auto bcn_frame = mgmt_bcn_frame.NextFrame();
    Span<const uint8_t> ie_chain = bcn_frame.body_data();
    zx_status_t status = it->second.ProcessBeacon(*bcn_frame.hdr(), ie_chain, rx_info);
    if (status != ZX_OK) {
        debugbcn("Failed to handle beacon (err %3d): BSSID %s timestamp: %15" PRIu64 "\n", status,
                 MACSTR(bssid), bcn_frame.hdr()->timestamp);
    }
}

OffChannelRequest Scanner::CreateOffChannelRequest() {
    return OffChannelRequest{.chan = ScanChannel(),
                             .duration = WLAN_TU(req_->max_channel_time),
                             .handler = &off_channel_handler_};
}

void Scanner::HandleHwScanAborted() {
    if (!IsRunning()) {
        errorf("got a HwScanAborted event while the scanner is not running\n");
        return;
    }
    errorf("scanner: hardware scan was aborted. Throwing out %zu BSS descriptions\n",
           current_bss_.size());
    SendScanEnd(device_, req_->txn_id, wlan_mlme::ScanResultCodes::INTERNAL_ERROR);
    Reset();
}

void Scanner::HandleHwScanComplete() {
    if (!IsRunning()) {
        errorf("got a HwScanComplete event while the scanner is not running\n");
        return;
    }
    SendResultsAndReset();
}

void Scanner::SendResultsAndReset() {
    zx_status_t status = SendResults(device_, req_->txn_id, current_bss_);
    if (status == ZX_OK) {
        SendScanEnd(device_, req_->txn_id, wlan_mlme::ScanResultCodes::SUCCESS);
    } else {
        errorf("scanner: failed to send results: %s\n", zx_status_get_string(status));
        SendScanEnd(device_, req_->txn_id, wlan_mlme::ScanResultCodes::INTERNAL_ERROR);
    }
    Reset();
}

}  // namespace wlan
