// Copyright 2018 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/common/buffer_writer.h>
#include <wlan/common/write_element.h>
#include <wlan/mlme/ap/beacon_sender.h>
#include <wlan/mlme/ap/bss_interface.h>
#include <wlan/mlme/mac_frame.h>
#include <wlan/mlme/packet.h>
#include <wlan/mlme/rates_elements.h>
#include <wlan/mlme/service.h>
#include <wlan/mlme/timer.h>

#include <fbl/unique_ptr.h>
#include <fuchsia/wlan/mlme/c/fidl.h>
#include <fuchsia/wlan/mlme/cpp/fidl.h>

#include "mock_device.h"
#include "test_bss.h"

#include <gtest/gtest.h>

namespace wlan {
namespace {

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

struct MockBss : public BssInterface {
    zx_status_t ScheduleTimeout(wlan_tu_t tus, const common::MacAddr& client_addr,
                                TimeoutId* id) {
        return ZX_OK;
    }

    void CancelTimeout(TimeoutId id) { }

    const common::MacAddr& bssid() const { return bssid_; }
    uint64_t timestamp() { return 0; }

    seq_t NextSeq(const MgmtFrameHeader& hdr) { return 0; }
    seq_t NextSeq(const MgmtFrameHeader& hdr, uint8_t aci) { return 0; }
    seq_t NextSeq(const DataFrameHeader& hdr) { return 0; }

    std::optional<DataFrame<LlcHeader>> EthToDataFrame(const EthFrame& eth_frame,
                                                       bool needs_protection) {
        return std::nullopt;
    }

    bool IsRsn() const { return false; }
    HtConfig Ht() const { return {}; }
    const Span<const SupportedRate> Rates() const { return {}; }

    zx_status_t SendMgmtFrame(MgmtFrame<>&& mgmt_frame) { return ZX_ERR_NOT_SUPPORTED; }
    zx_status_t SendDataFrame(DataFrame<>&& data_frame, uint32_t flags) {
        return ZX_ERR_NOT_SUPPORTED;
    }
    zx_status_t DeliverEthernet(Span<const uint8_t> frame) { return ZX_ERR_NOT_SUPPORTED; }

    void OnPreTbtt() {}
    void OnBcnTxComplete() {}

    wlan_channel_t Chan() const { return {}; }

    common::MacAddr bssid_ = common::MacAddr(kBssid1);
};

struct BeaconSenderTest : public ::testing::Test {
    BeaconSenderTest() : bcn_sender(&device) {}

    MockBss bss;
    MockDevice device;
    BeaconSender bcn_sender;
    PsCfg ps_cfg;
};

TEST_F(BeaconSenderTest, Start) {
    ASSERT_FALSE(device.beaconing_enabled);

    bcn_sender.Start(&bss, ps_cfg, CreateStartRequest(false));

    ASSERT_TRUE(device.beaconing_enabled);
    ASSERT_EQ(device.beacon.get(), nullptr);

    bcn_sender.UpdateBeacon(ps_cfg);

    auto pkt = std::move(device.beacon);
    EXPECT_TRUE(device.beaconing_enabled);
    ASSERT_NE(pkt, nullptr);

    auto checked = MgmtFrameView<Beacon>::CheckType(pkt.get());
    ASSERT_TRUE(checked);
    auto beacon_frame = checked.CheckLength();
    ASSERT_TRUE(beacon_frame);
}

TEST_F(BeaconSenderTest, ProbeRequest) {
    bcn_sender.Start(&bss, ps_cfg, CreateStartRequest(false));

    ASSERT_TRUE(device.wlan_queue.empty());

    uint8_t buffer[1024] = {};
    BufferWriter elem_w(buffer);
    common::WriteSsid(&elem_w, kSsid);
    RatesWriter rates_writer{kSupportedRates};
    rates_writer.WriteSupportedRates(&elem_w);
    rates_writer.WriteExtendedSupportedRates(&elem_w);
    common::WriteDsssParamSet(&elem_w, kBssChannel.primary);

    common::MacAddr ra(kClientAddress);
    bcn_sender.SendProbeResponse(ra, elem_w.WrittenData());

    ASSERT_FALSE(device.wlan_queue.empty());
    auto pkt = std::move(*device.wlan_queue.begin());

    auto checked = MgmtFrameView<ProbeResponse>::CheckType(pkt.pkt.get());
    ASSERT_TRUE(checked);
    auto beacon_frame = checked.CheckLength();
    ASSERT_TRUE(beacon_frame);

    EXPECT_EQ(pkt.cbw, CBW20);
    EXPECT_EQ(pkt.phy, WLAN_PHY_OFDM);
    EXPECT_EQ(pkt.flags, 0u);
}

TEST(BeaconSender, ShouldSendProbeResponse) {
    const uint8_t our_ssid[] = {'f', 'o', 'o'};

    const uint8_t no_ssid[] = {1, 1, 1};
    EXPECT_TRUE(ShouldSendProbeResponse(no_ssid, our_ssid));

    const uint8_t different_ssid[] = {0, 3, 'b', 'a', 'r', 1, 1, 1};
    EXPECT_FALSE(ShouldSendProbeResponse(different_ssid, our_ssid));

    const uint8_t matching_ssid[] = {0, 3, 'f', 'o', 'o', 1, 1, 1};
    EXPECT_TRUE(ShouldSendProbeResponse(matching_ssid, our_ssid));

    const uint8_t wildcard_ssid[] = {0, 0, 1, 1, 1};
    EXPECT_TRUE(ShouldSendProbeResponse(wildcard_ssid, our_ssid));

    const uint8_t malformed_ssid[35] = {
        0,
        33,
    };
    EXPECT_FALSE(ShouldSendProbeResponse(malformed_ssid, our_ssid));
}

}  // namespace
}  // namespace wlan
