// 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 <gtest/gtest.h>

#include "../minstrel.h"
#include "../probe_sequence.h"

#include <fbl/algorithm.h>
#include <lib/timekeeper/test_clock.h>
#include <test_timer.h>  // //garnet/lib/wlan/mlme/tests
#include <wlan/mlme/timer.h>
#include <wlan/mlme/timer_manager.h>
#include <wlan/protocol/info.h>

namespace wlan {
namespace {

namespace wlan_minstrel = ::fuchsia::wlan::minstrel;

ProbeSequence::ProbeTable SequentialTable() {
    ProbeSequence::ProbeTable sequence_table;
    for (uint8_t i = 0; i < ProbeSequence::kNumProbeSequece; ++i) {
        for (tx_vec_idx_t j = kStartIdx; j <= kMaxValidIdx; ++j) {
            sequence_table[i][j - kStartIdx] = j;
        }
    }
    return sequence_table;
}

static const common::MacAddr kTestMacAddr({50, 53, 51, 56, 55, 52});
static const uint8_t kBasicRateBit = 0b10000000;

struct MinstrelTest : public ::testing::Test {
    MinstrelTest()
        : minstrel_(MinstrelRateSelector(fbl::make_unique<TestTimer>(0, &clock),
                                         ProbeSequence(SequentialTable()), zx::msec(100))) {
        kTestMacAddr.CopyTo(assoc_ctx_ht_.bssid);
    }

    void AdvanceTimeBy(zx::duration duration) { clock.Set(clock.Now() + duration); }

    timekeeper::TestClock clock;
    MinstrelRateSelector minstrel_;
    wlan_assoc_ctx_t assoc_ctx_ht_{
        .rates_cnt = 12,
        .rates = {2, 4, 11, 22, 12 | kBasicRateBit, 18, 24, 36, 48, 72, 96, 108 | kBasicRateBit},
        .has_ht_cap = true,
        .ht_cap =
            {
                // left->right: SGI 40 MHz, SGI 20 MHz, 40 MHz
                .ht_capability_info = 0b01100010,
                .supported_mcs_set =
                    {
                        0xff,  // MCS 0-7
                        0xff,  // MCS 8-15
                    },
            },
    };
    // Note: 16 is the max throughput and 136 is the highest basic rate. They will never be probed.
    const tx_vec_idx_t want_probe_idx_[22] =
        // clang-format off
        {1,   2,   3,   4,   5,   6,   7,   8,
         9,   10,  11,  12,  13,  14,  15,  /* 16 ,*/
         129, 130, 131, 132, 133, 134, 135, /* 136 */};
        // clang-format on
};

TEST_F(MinstrelTest, AddPeer) {
    minstrel_.AddPeer(assoc_ctx_ht_);
    EXPECT_TRUE(minstrel_.IsActive());

    wlan_minstrel::Peers peers;
    zx_status_t status = minstrel_.GetListToFidl(&peers);
    EXPECT_EQ(ZX_OK, status);
    EXPECT_EQ(1ULL, peers.peers.size());

    wlan_minstrel::Peer peer;
    status = minstrel_.GetStatsToFidl(kTestMacAddr, &peer);
    EXPECT_EQ(ZX_OK, status);
    EXPECT_EQ(kTestMacAddr, common::MacAddr(peer.mac_addr.data()));
    // TODO(eyw): size would be 40 if 40 MHz is supported, 72 if 40 MHz and SGI are both supported.
    EXPECT_EQ(24ULL, peer.entries.size());
    EXPECT_EQ(16, peer.max_tp);
    EXPECT_EQ(peer.entries[0].tx_vector_idx, peer.max_probability);
    EXPECT_EQ(kErpStartIdx + kErpNumTxVector - 1, peer.basic_highest);
    EXPECT_EQ(kErpStartIdx + kErpNumTxVector - 1, peer.basic_max_probability);
}

TEST_F(MinstrelTest, RemovePeer) {
    // Add a peer to be removed later.
    minstrel_.AddPeer(assoc_ctx_ht_);
    EXPECT_TRUE(minstrel_.IsActive());

    wlan_minstrel::Peers peers;
    zx_status_t status = minstrel_.GetListToFidl(&peers);
    EXPECT_EQ(ZX_OK, status);
    EXPECT_EQ(1ULL, peers.peers.size());

    // Remove the peer using its mac address.
    minstrel_.RemovePeer(kTestMacAddr);
    EXPECT_FALSE(minstrel_.IsActive());

    status = minstrel_.GetListToFidl(&peers);
    EXPECT_EQ(ZX_OK, status);
    EXPECT_TRUE(peers.peers.empty());

    wlan_minstrel::Peer peer;
    status = minstrel_.GetStatsToFidl(kTestMacAddr, &peer);
    EXPECT_EQ(ZX_ERR_NOT_FOUND, status);
}

TEST_F(MinstrelTest, HandleTimeout) {
    clock.Set(zx::time(0));
    minstrel_.AddPeer(assoc_ctx_ht_);

    AdvanceTimeBy(zx::msec(99));
    EXPECT_FALSE(minstrel_.HandleTimeout());
    AdvanceTimeBy(zx::msec(1));
    EXPECT_TRUE(minstrel_.HandleTimeout());
}

TEST_F(MinstrelTest, UpdateStats) {
    // .tx_status_entry contains up to 8 entries
    // All entries except the last one indicates failed attempts.
    // The last entry can be successful or unsuccessful based on .success
    wlan_tx_status_t tx_status{
        .success = true,
        .tx_status_entry =
            {
                // HT, CBW20, GI 800 ns,
                {16, 1},  // MCS 7, fail
                {15, 1},  // MCS 6, fail
                {14, 1},  // MCS 5, fail
                {13, 1},  // MCS 4, succeed because |.success| is true
            },
    };

    clock.Set(zx::time(0));
    minstrel_.AddPeer(assoc_ctx_ht_);
    kTestMacAddr.CopyTo(tx_status.peer_addr);

    minstrel_.HandleTxStatusReport(tx_status);
    wlan_minstrel::Peer peer;
    EXPECT_EQ(ZX_OK, minstrel_.GetStatsToFidl(kTestMacAddr, &peer));
    // tx_status collected but NOT been processed yet
    // it will be processed every 100 ms, when HandleTimeout() is called.
    EXPECT_EQ(16, peer.max_tp);
    EXPECT_EQ(peer.entries[0].tx_vector_idx, peer.max_probability);

    AdvanceTimeBy(zx::msec(100));
    EXPECT_TRUE(minstrel_.HandleTimeout());  // tx_status are processed at HandleTimeout()
    EXPECT_EQ(ZX_OK, minstrel_.GetStatsToFidl(kTestMacAddr, &peer));
    EXPECT_EQ(13, peer.max_tp);           // Everything above 45 has 0 success, thus 0 throughput
    EXPECT_EQ(13, peer.max_probability);  // 45 has 100% success rate

    // 45 fails, but 41 (MCS 0) succeeds because |.success| is still true
    wlan_tx_status_entry_t entries[WLAN_TX_STATUS_MAX_ENTRY]{{13, 1}, {9, 1}};
    memcpy(tx_status.tx_status_entry, &entries, sizeof(tx_status.tx_status_entry));
    // after every cycle, success rate of 45 decrease to 75% of it previous value,
    // success rate of 41 stays at 100% because of continuous positive outcome
    // After enough cycles, 45's (success_rate * theoretical_throughput) becomes lower than 41.
    for (int i = 0; i < 10; ++i) {
        minstrel_.HandleTxStatusReport(tx_status);
        AdvanceTimeBy(zx::msec(100));
        EXPECT_TRUE(minstrel_.HandleTimeout());
        EXPECT_EQ(ZX_OK, minstrel_.GetStatsToFidl(kTestMacAddr, &peer));
        EXPECT_EQ(9, peer.max_probability);
    }
    EXPECT_EQ(ZX_OK, minstrel_.GetStatsToFidl(kTestMacAddr, &peer));
    EXPECT_EQ(9, peer.max_tp);
}

TEST_F(MinstrelTest, HtIsMyFavorite) {
    wlan_tx_status_t failed_ht_tx_status {
      .success = false,
      .tx_status_entry =
          {
              // MCS 8-15 all fail
              {kHtStartIdx + 15, 1},
              {kHtStartIdx + 14, 1},
              {kHtStartIdx + 13, 1},
              {kHtStartIdx + 12, 1},
              {kHtStartIdx + 11, 1},
              {kHtStartIdx + 10, 1},
              {kHtStartIdx + 9, 1},
              {kHtStartIdx + 8, 1},
          }
    };

    wlan_tx_status_t ht_tx_status{
        .success = true,
        .tx_status_entry =
            {
                // MCS 1-7 all fail, only MCS 0 succeeds.
                {kHtStartIdx + 7, 1},
                {kHtStartIdx + 6, 1},
                {kHtStartIdx + 5, 1},
                {kHtStartIdx + 4, 1},
                {kHtStartIdx + 3, 1},
                {kHtStartIdx + 2, 1},
                {kHtStartIdx + 1, 1},
                // Lowest HT MCS with success probability 11% == (1/9) note: 0.1f < 1 - 0.9f
                {kHtStartIdx + 0, 9},
            },
    };

    wlan_tx_status_t erp_tx_status {
        .success = true,
        .tx_status_entry =
        {
            // Highest ERP rate with success probability 100% == (1/1)
            {kErpStartIdx + kErpNumTxVector - 1, 1},
        },
    };

    clock.Set(zx::time(0));
    minstrel_.AddPeer(assoc_ctx_ht_);
    kTestMacAddr.CopyTo(failed_ht_tx_status.peer_addr);
    kTestMacAddr.CopyTo(ht_tx_status.peer_addr);
    kTestMacAddr.CopyTo(erp_tx_status.peer_addr);

    minstrel_.HandleTxStatusReport(failed_ht_tx_status);
    minstrel_.HandleTxStatusReport(ht_tx_status);
    minstrel_.HandleTxStatusReport(erp_tx_status);
    AdvanceTimeBy(zx::msec(100));
    ASSERT_TRUE(minstrel_.HandleTimeout());  // tx_status are processed at HandleTimeout()
    wlan_minstrel::Peer peer;
    EXPECT_EQ(ZX_OK, minstrel_.GetStatsToFidl(kTestMacAddr, &peer));
    // HT is selected for max_tp even though it has lower throughput
    EXPECT_EQ(kHtStartIdx, peer.max_tp);
    // HT is selected for max_probability even though it has lower probability
    EXPECT_EQ(kHtStartIdx, peer.max_probability);
}


std::unordered_set<tx_vec_idx_t> GetAllIndices(const wlan_minstrel::Peer& peer) {
    std::unordered_set<tx_vec_idx_t> indices;
    for (const auto& entry : peer.entries) {
        indices.emplace(entry.tx_vector_idx);
    }
    return indices;
}

TEST_F(MinstrelTest, AddMissingTxVector) {
    clock.Set(zx::time(0));

    assoc_ctx_ht_.rates_cnt = 10;
    const uint8_t fewer_rates[10] = {2, 4, 11, 22, 12, 18, 24, 36, 48, 72};  // missing 96 and 108
    std::copy(std::cbegin(fewer_rates), std::cend(fewer_rates), assoc_ctx_ht_.rates);
    minstrel_.AddPeer(assoc_ctx_ht_);

    wlan_tx_status_t tx_status{
        .success = true,
        .tx_status_entry =
            {
                // ERP, CBW20, GI 800 ns,
                {kErpStartIdx + kErpNumTxVector - 1, 1},  // MCS 7, 108, non-present, fail
                {kErpStartIdx + kErpNumTxVector - 3, 1},  // MCS 5, 72,  present,     succeed
            },
    };
    kTestMacAddr.CopyTo(tx_status.peer_addr);

    wlan_minstrel::Peer peer;
    EXPECT_EQ(ZX_OK, minstrel_.GetStatsToFidl(kTestMacAddr, &peer));
    auto indices = GetAllIndices(peer);
    EXPECT_FALSE(indices.count(kErpStartIdx + kErpNumTxVector - 1));

    minstrel_.HandleTxStatusReport(tx_status);
    EXPECT_EQ(ZX_OK, minstrel_.GetStatsToFidl(kTestMacAddr, &peer));
    indices = GetAllIndices(peer);
    EXPECT_TRUE(indices.count(kErpStartIdx + kErpNumTxVector - 1));
}

TEST_F(MinstrelTest, DataFramesEligibleForProbing) {
    clock.Set(zx::time(0));
    minstrel_.AddPeer(assoc_ctx_ht_);
    wlan_minstrel::Peer peer;
    EXPECT_EQ(ZX_OK, minstrel_.GetStatsToFidl(kTestMacAddr, &peer));

    FrameControl fc;
    fc.set_type(FrameType::kData);
    for (tx_vec_idx_t i = 0; i < kProbeInterval * fbl::count_of(want_probe_idx_); ++i) {
        const tx_vec_idx_t idx = minstrel_.GetTxVectorIdx(fc, kTestMacAddr, 0);
        if (i % kProbeInterval == kProbeInterval - 1) {
            tx_vec_idx_t want = want_probe_idx_[(i + 1) / kProbeInterval - 1];
            if (want != idx) { printf("probe mismatch #%d\n", i); }
            EXPECT_EQ(want, idx);
        } else {
            if (peer.max_tp != idx) { printf("non-probe mismatch #%d\n", i); }
            EXPECT_EQ(peer.max_tp, idx);
        }
    }
}

}  // namespace
}  // namespace wlan
