// Copyright 2022 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.

// To test PHY device callback functions.

#include <lib/async/cpp/task.h>
#include <lib/fdio/directory.h>
#include <lib/sync/cpp/completion.h>
#include <zircon/listnode.h>
#include <zircon/syscalls.h>

#include <iterator>

#include <gtest/gtest.h>

#include "fidl/fuchsia.wlan.phyimpl/cpp/wire_types.h"
#include "third_party/iwlwifi/platform/banjo/common.h"

extern "C" {
#include "third_party/iwlwifi/mvm/mvm.h"
}

#include "third_party/iwlwifi/platform/ieee80211.h"
#include "third_party/iwlwifi/platform/mvm-mlme.h"
#include "third_party/iwlwifi/platform/wlanphyimpl-device.h"
#include "third_party/iwlwifi/test/fake-ucode-test.h"

namespace wlan::testing {
namespace {

constexpr size_t kListenInterval = 100;
constexpr zx_handle_t kDummyMlmeChannel = 73939133;  // An arbitrary value not ZX_HANDLE_INVALID

class WlanPhyImplDeviceTest : public FakeUcodeTest {
 public:
  WlanPhyImplDeviceTest()
      : FakeUcodeTest({IWL_UCODE_TLV_CAPA_LAR_SUPPORT}, {IWL_UCODE_TLV_API_WIFI_MCC_UPDATE}),
        mvmvif_sta_{
            .mvm = iwl_trans_get_mvm(sim_trans_.iwl_trans()),
            .mac_role = WLAN_MAC_ROLE_CLIENT,
            .bss_conf =
                {
                    .beacon_int = kListenInterval,
                },
        },
        test_arena_(nullptr) {
    sim_driver_ = sim_trans_.sim_driver();

    auto endpoints = fdf::CreateEndpoints<fuchsia_wlan_phyimpl::WlanPhyImpl>();
    EXPECT_FALSE(endpoints.is_error());

    client_ = fdf::WireSyncClient<fuchsia_wlan_phyimpl::WlanPhyImpl>(std::move(endpoints->client));

    // `DdkServiceConnect` starts a FIDL server that bounds to the dispatcher of
    // the caller. The FIDL protocol that is being served uses driver transport
    // and so it must be bound to an fdf dispatcher.
    libsync::Completion connected;
    async::PostTask(sim_trans_.async_driver_dispatcher(), [&]() {
      sim_driver_->ServiceConnectHandler(sim_trans_.fdf_driver_dispatcher(),
                                         std::move(endpoints->server));
      connected.Signal();
    });
    connected.Wait();

    // Create test arena.
    constexpr uint32_t kTag = 'TEST';
    test_arena_ = fdf::Arena(kTag);
  }

  ~WlanPhyImplDeviceTest() = default;

  zx_status_t CreateIface(fuchsia_wlan_common::WlanMacRole role, uint16_t* iface_id_out) {
    auto ch = ::zx::channel(kDummyMlmeChannel);
    static fidl::Arena arena;
    auto builder = fuchsia_wlan_phyimpl::wire::WlanPhyImplCreateIfaceRequest::Builder(arena);
    builder.role(role);
    builder.mlme_channel(std::move(ch));
    auto result = client_.buffer(test_arena_)->CreateIface(builder.Build());
    EXPECT_EQ(result.status(), ZX_OK);
    if (result->is_error()) {
      // Returns an invalid iface id.
      *iface_id_out = MAX_NUM_MVMVIF;
      return result->error_value();
    }

    *iface_id_out = result->value()->iface_id();
    return ZX_OK;
  }

  zx_status_t DestroyIface(uint16_t iface_id) {
    static fidl::Arena arena;
    auto builder = fuchsia_wlan_phyimpl::wire::WlanPhyImplDestroyIfaceRequest::Builder(arena);
    builder.iface_id(iface_id);

    auto result = client_.buffer(test_arena_)->DestroyIface(builder.Build());
    EXPECT_TRUE(result.ok());
    if (result->is_error()) {
      return result->error_value();
    }

    return ZX_OK;
  }

 protected:
  struct iwl_mvm_vif mvmvif_sta_;  // The mvm_vif settings for station role.
  wlan::iwlwifi::SimTransIwlwifiDriver* sim_driver_;

  fdf::WireSyncClient<fuchsia_wlan_phyimpl::WlanPhyImpl> client_;
  fdf::Arena test_arena_;
  libsync::Completion completion_;
};

/////////////////////////////////////       PHY       //////////////////////////////////////////////

TEST_F(WlanPhyImplDeviceTest, GetSupportedMacRoles) {
  auto result = client_.buffer(test_arena_)->GetSupportedMacRoles();
  ASSERT_TRUE(result.ok());
  ASSERT_FALSE(result->is_error());
  ASSERT_TRUE(result->value()->has_supported_mac_roles());
  EXPECT_EQ(result->value()->supported_mac_roles().count(), 1);
  EXPECT_EQ(result->value()->supported_mac_roles().data()[0],
            fuchsia_wlan_common::WlanMacRole::kClient);
}

TEST_F(WlanPhyImplDeviceTest, PartialCreateCleanup) {
  wlan_phy_impl_create_iface_req_t req = {
      .role = WLAN_MAC_ROLE_CLIENT,
      .mlme_channel = kDummyMlmeChannel,
  };
  uint16_t iface_id;
  struct iwl_trans* iwl_trans = sim_trans_.iwl_trans();

  // Test input null pointers
  ASSERT_EQ(ZX_OK, phy_create_iface(iwl_trans, &req, &iface_id));

  // Ensure mvmvif got created and indexed.
  struct iwl_mvm* mvm = iwl_trans_get_mvm(iwl_trans);
  ASSERT_NE(nullptr, mvm->mvmvif[iface_id]);

  // Ensure partial create failure removes it from the index.
  phy_create_iface_undo(iwl_trans, iface_id);
  ASSERT_EQ(nullptr, mvm->mvmvif[iface_id]);
}

TEST_F(WlanPhyImplDeviceTest, CreateIfaceNegativeTest) {
  static fidl::Arena arena;

  // Both role and channel not populated.
  {
    auto builder = fuchsia_wlan_phyimpl::wire::WlanPhyImplCreateIfaceRequest::Builder(arena);
    auto result = client_.buffer(test_arena_)->CreateIface(builder.Build());
    ASSERT_TRUE(result.ok());
    ASSERT_TRUE(result->is_error());
    EXPECT_EQ(ZX_ERR_INVALID_ARGS, result->error_value());
  }

  // Role is set, but not channel.
  {
    auto builder = fuchsia_wlan_phyimpl::wire::WlanPhyImplCreateIfaceRequest::Builder(arena);
    builder.role(fuchsia_wlan_common::wire::WlanMacRole::kClient);
    auto result = client_.buffer(test_arena_)->CreateIface(builder.Build());
    ASSERT_TRUE(result.ok());
    ASSERT_TRUE(result->is_error());
    ASSERT_EQ(ZX_ERR_INVALID_ARGS, result->error_value());
  }

  // Channel is set, but not the role.
  {
    auto ch = ::zx::channel(kDummyMlmeChannel);
    auto builder = fuchsia_wlan_phyimpl::wire::WlanPhyImplCreateIfaceRequest::Builder(arena);
    builder.mlme_channel(std::move(ch));
    auto result = client_.buffer(test_arena_)->CreateIface(builder.Build());
    EXPECT_TRUE(result.ok());
    EXPECT_TRUE(result->is_error());
    ASSERT_EQ(ZX_ERR_INVALID_ARGS, result->error_value());
  }
}

TEST_F(WlanPhyImplDeviceTest, DestroyIfaceNegativeTest) {
  static fidl::Arena arena;

  // iface_id not populated.
  auto builder = fuchsia_wlan_phyimpl::wire::WlanPhyImplDestroyIfaceRequest::Builder(arena);
  auto result = client_.buffer(test_arena_)->DestroyIface(builder.Build());
  ASSERT_TRUE(result.ok());
  ASSERT_TRUE(result->is_error());
  ASSERT_EQ(ZX_ERR_INVALID_ARGS, result->error_value());
}

TEST_F(WlanPhyImplDeviceTest, CreateDestroySingleInterface) {
  uint16_t iface_id;

  // Test invalid inputs
  EXPECT_EQ(ZX_ERR_INVALID_ARGS, DestroyIface(MAX_NUM_MVMVIF));
  EXPECT_EQ(ZX_ERR_NOT_FOUND, DestroyIface(0));  // hasn't been added yet.

  // To verify the internal state of MVM driver.
  struct iwl_mvm* mvm = iwl_trans_get_mvm(sim_trans_.iwl_trans());

  // Add interface
  EXPECT_EQ(ZX_OK, CreateIface(fuchsia_wlan_common::wire::WlanMacRole::kClient, &iface_id));
  ASSERT_EQ(iface_id, 0);  // the first interface should have id 0.
  struct iwl_mvm_vif* mvmvif = mvm->mvmvif[0];
  ASSERT_NE(mvmvif, nullptr);
  ASSERT_EQ(mvmvif->mac_role,
            static_cast<wlan_mac_role_t>(fuchsia_wlan_common::wire::WlanMacRole::kClient));
  // Count includes phy device in addition to the newly created mac device.
  ASSERT_EQ(sim_driver_->DeviceCount(), 1);

  // Remove interface
  EXPECT_EQ(ZX_OK, DestroyIface(0));
  ASSERT_EQ(mvm->mvmvif[0], nullptr);
  ASSERT_EQ(sim_driver_->DeviceCount(), 0);
}

TEST_F(WlanPhyImplDeviceTest, CreateDestroyMultipleInterfaces) {
  struct iwl_trans* iwl_trans = sim_trans_.iwl_trans();
  struct iwl_mvm* mvm = iwl_trans_get_mvm(iwl_trans);  // To verify the internal state of MVM
  uint16_t iface_id;

  // Add 1st interface
  EXPECT_EQ(ZX_OK, CreateIface(fuchsia_wlan_common::wire::WlanMacRole::kClient, &iface_id));
  ASSERT_EQ(iface_id, 0);
  ASSERT_NE(mvm->mvmvif[0], nullptr);
  ASSERT_EQ(mvm->mvmvif[0]->mac_role, WLAN_MAC_ROLE_CLIENT);
  ASSERT_EQ(sim_driver_->DeviceCount(), 1);

  // Add 2nd interface
  EXPECT_EQ(ZX_OK, CreateIface(fuchsia_wlan_common::wire::WlanMacRole::kClient, &iface_id));
  ASSERT_EQ(iface_id, 1);
  ASSERT_NE(mvm->mvmvif[1], nullptr);
  ASSERT_EQ(mvm->mvmvif[1]->mac_role, WLAN_MAC_ROLE_CLIENT);
  ASSERT_EQ(sim_driver_->DeviceCount(), 2);

  // Add 3rd interface
  EXPECT_EQ(ZX_OK, CreateIface(fuchsia_wlan_common::wire::WlanMacRole::kClient, &iface_id));
  ASSERT_EQ(iface_id, 2);
  ASSERT_NE(mvm->mvmvif[2], nullptr);
  ASSERT_EQ(mvm->mvmvif[2]->mac_role, WLAN_MAC_ROLE_CLIENT);
  ASSERT_EQ(sim_driver_->DeviceCount(), 3);

  // Remove the 2nd interface
  EXPECT_EQ(ZX_OK, DestroyIface(1));
  ASSERT_EQ(mvm->mvmvif[1], nullptr);
  ASSERT_EQ(sim_driver_->DeviceCount(), 2);

  // Add a new interface and it should be the 2nd one.
  EXPECT_EQ(ZX_OK, CreateIface(fuchsia_wlan_common::wire::WlanMacRole::kClient, &iface_id));
  ASSERT_EQ(iface_id, 1);
  ASSERT_NE(mvm->mvmvif[1], nullptr);
  ASSERT_EQ(mvm->mvmvif[1]->mac_role, WLAN_MAC_ROLE_CLIENT);
  ASSERT_EQ(sim_driver_->DeviceCount(), 3);

  // Add 4th interface
  EXPECT_EQ(ZX_OK, CreateIface(fuchsia_wlan_common::wire::WlanMacRole::kClient, &iface_id));
  ASSERT_EQ(iface_id, 3);
  ASSERT_NE(mvm->mvmvif[3], nullptr);
  ASSERT_EQ(mvm->mvmvif[3]->mac_role, WLAN_MAC_ROLE_CLIENT);
  ASSERT_EQ(sim_driver_->DeviceCount(), 4);

  // Add 5th interface and it should fail
  EXPECT_EQ(ZX_ERR_NO_RESOURCES,
            CreateIface(fuchsia_wlan_common::wire::WlanMacRole::kClient, &iface_id));
  ASSERT_EQ(sim_driver_->DeviceCount(), 4);

  // Remove the 2nd interface
  EXPECT_EQ(ZX_OK, DestroyIface(1));
  ASSERT_EQ(mvm->mvmvif[1], nullptr);
  ASSERT_EQ(sim_driver_->DeviceCount(), 3);

  // Remove the 3rd interface
  EXPECT_EQ(ZX_OK, DestroyIface(2));
  ASSERT_EQ(mvm->mvmvif[2], nullptr);
  ASSERT_EQ(sim_driver_->DeviceCount(), 2);

  // Remove the 4th interface
  EXPECT_EQ(ZX_OK, DestroyIface(3));
  ASSERT_EQ(mvm->mvmvif[3], nullptr);
  ASSERT_EQ(sim_driver_->DeviceCount(), 1);

  // Remove the 1st interface
  EXPECT_EQ(ZX_OK, DestroyIface(0));
  ASSERT_EQ(mvm->mvmvif[0], nullptr);
  ASSERT_EQ(sim_driver_->DeviceCount(), 0);

  // Remove the 1st interface again and it should fail.
  EXPECT_EQ(ZX_ERR_NOT_FOUND, DestroyIface(0));
  ASSERT_EQ(sim_driver_->DeviceCount(), 0);
}

TEST_F(WlanPhyImplDeviceTest, GetCountry) {
  auto result = client_.buffer(test_arena_)->GetCountry();
  ASSERT_TRUE(result.ok());
  ASSERT_FALSE(result->is_error());
  auto& country = result.value();
  EXPECT_EQ('Z', country->alpha2().data()[0]);
  EXPECT_EQ('Z', country->alpha2().data()[1]);
}

TEST_F(WlanPhyImplDeviceTest, SetCountry) {
  auto country = fuchsia_wlan_phyimpl::wire::WlanPhyCountry::WithAlpha2({'U', 'S'});
  auto result = client_.buffer(test_arena_)->SetCountry(country);
  ASSERT_TRUE(result.ok());
  ASSERT_TRUE(result->is_error());
  ASSERT_EQ(ZX_ERR_NOT_SUPPORTED, result->error_value());
}

TEST_F(WlanPhyImplDeviceTest, ClearCountry) {
  auto result = client_.buffer(test_arena_)->ClearCountry();
  ASSERT_TRUE(result.ok());
  ASSERT_TRUE(result->is_error());
  ASSERT_EQ(ZX_ERR_NOT_SUPPORTED, result->error_value());
}

TEST_F(WlanPhyImplDeviceTest, SetPowerSaveMode) {
  static fidl::Arena arena;
  auto builder = fuchsia_wlan_phyimpl::wire::WlanPhyImplSetPowerSaveModeRequest::Builder(arena);
  auto result = client_.buffer(test_arena_)->SetPowerSaveMode(builder.Build());
  ASSERT_TRUE(result.ok());
  ASSERT_TRUE(result->is_error());
  ASSERT_EQ(ZX_ERR_NOT_SUPPORTED, result->error_value());
}

TEST_F(WlanPhyImplDeviceTest, GetPowerSaveMode) {
  auto result = client_.buffer(test_arena_)->GetPowerSaveMode();
  ASSERT_TRUE(result.ok());
  ASSERT_TRUE(result->is_error());
  ASSERT_EQ(ZX_ERR_NOT_SUPPORTED, result->error_value());
}

}  // namespace
}  // namespace wlan::testing
