/*
 * Copyright (C) 2016, The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <array>
#include <memory>
#include <vector>

#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <wifi_system_test/mock_interface_tool.h>

#include "wificond/client_interface_impl.h"
#include "wificond/tests/mock_i_send_mgmt_frame_event.h"
#include "wificond/tests/mock_netlink_manager.h"
#include "wificond/tests/mock_netlink_utils.h"
#include "wificond/tests/mock_scan_utils.h"

using android::wifi_system::MockInterfaceTool;
using std::unique_ptr;
using std::vector;
using testing::Mock;
using testing::NiceMock;
using testing::Return;
using testing::StrictMock;
using testing::_;

namespace android {
namespace wificond {
namespace {

const uint32_t kTestWiphyIndex = 2;
const char kTestInterfaceName[] = "testwifi0";
const uint32_t kTestInterfaceIndex = 42;
const uint64_t kCookie = 42;
const int32_t kAutoMcs = -1;
const int32_t kMcs = 5;
const uint8_t kTestFrame[] = {0x00, 0x01, 0x02, 0x03};

class ClientInterfaceImplTest : public ::testing::Test {
 protected:

  void SetUp() override {
    SetUp(WiphyFeatures());
  }

  /**
   * call SetUp(WiphyFeatures wiphy_features) in your test function if
   * you would like to change WiphyFeatures.
   */
  void SetUp(WiphyFeatures wiphy_features) {
    EXPECT_CALL(*netlink_utils_,
                SubscribeMlmeEvent(kTestInterfaceIndex, _));
    EXPECT_CALL(*netlink_utils_,
                GetWiphyInfo(kTestWiphyIndex, _, _, _))
      .WillOnce([wiphy_features](uint32_t wiphy_index, BandInfo* out_band_info,
          ScanCapabilities* out_scan_capabilities,
          WiphyFeatures* out_wiphy_features) {
        *out_wiphy_features = wiphy_features;
        return true;
      });
    EXPECT_CALL(*netlink_utils_,
                SubscribeFrameTxStatusEvent(kTestInterfaceIndex, _))
        .WillOnce([this](uint32_t interface_index,
            OnFrameTxStatusEventHandler handler) {
          frame_tx_status_event_handler_ = handler;
        });
    EXPECT_CALL(*netlink_utils_,
                SubscribeChannelSwitchEvent(kTestInterfaceIndex, _));
    client_interface_.reset(new ClientInterfaceImpl{
        kTestWiphyIndex,
        kTestInterfaceName,
        kTestInterfaceIndex,
        std::array<uint8_t, ETH_ALEN>{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
        if_tool_.get(),
        netlink_utils_.get(),
        scan_utils_.get()});
  }

  void TearDown() override {
    EXPECT_CALL(*netlink_utils_,
                UnsubscribeMlmeEvent(kTestInterfaceIndex));
    EXPECT_CALL(*netlink_utils_,
                UnsubscribeFrameTxStatusEvent(kTestInterfaceIndex));
    EXPECT_CALL(*netlink_utils_,
                UnsubscribeChannelSwitchEvent(kTestInterfaceIndex));
  }

  unique_ptr<NiceMock<MockInterfaceTool>> if_tool_{
      new NiceMock<MockInterfaceTool>};
  unique_ptr<NiceMock<MockNetlinkManager>> netlink_manager_{
      new NiceMock<MockNetlinkManager>()};
  unique_ptr<NiceMock<MockNetlinkUtils>> netlink_utils_{
      new NiceMock<MockNetlinkUtils>(netlink_manager_.get())};
  unique_ptr<NiceMock<MockScanUtils>> scan_utils_{
      new NiceMock<MockScanUtils>(netlink_manager_.get())};
  unique_ptr<ClientInterfaceImpl> client_interface_;
  OnFrameTxStatusEventHandler frame_tx_status_event_handler_;
  sp<StrictMock<MockISendMgmtFrameEvent>> send_mgmt_frame_event_{
      new StrictMock<MockISendMgmtFrameEvent>()};
};  // class ClientInterfaceImplTest

}  // namespace

/**
 * If the device does not support sending mgmt frame at specified MCS rate,
 * and the caller specifies a MCS < 0, the call should still succeed (and the
 * driver will determine the MCS rate automatically).
 */
TEST_F(ClientInterfaceImplTest, SendMgmtFrameMcsUnsupportedAutoSelectMcs) {
  EXPECT_CALL(*netlink_utils_,
      SendMgmtFrame(kTestInterfaceIndex,
          vector<uint8_t>(std::begin(kTestFrame), std::end(kTestFrame)),
          kAutoMcs, _))
    .WillOnce([](uint32_t interface_index, const vector<uint8_t>& frame,
        int32_t mcs, uint64_t* out_cookie) {
      *out_cookie = kCookie;
      return true;
    });

  EXPECT_CALL(*send_mgmt_frame_event_, OnAck(_));

  client_interface_->SendMgmtFrame(
      vector<uint8_t>(std::begin(kTestFrame), std::end(kTestFrame)),
      send_mgmt_frame_event_, kAutoMcs);
  frame_tx_status_event_handler_(kCookie, true);
}

/**
 * If the device does not support sending mgmt frame at specified MCS rate,
 * and the caller specifies a MCS >= 0, the call should fail.
 */
TEST_F(ClientInterfaceImplTest, SendMgmtFrameMcsUnsupportedCallerSpecifiedMcs) {
  EXPECT_CALL(*send_mgmt_frame_event_,
      OnFailure(send_mgmt_frame_event_->SEND_MGMT_FRAME_ERROR_MCS_UNSUPPORTED));

  client_interface_->SendMgmtFrame(
      vector<uint8_t>(std::begin(kTestFrame), std::end(kTestFrame)),
      send_mgmt_frame_event_, kMcs);
}

/**
 * If the device does support sending mgmt frame at specified MCS rate and the
 * user specifies a valid MCS rate, the call should succeed.
 */
TEST_F(ClientInterfaceImplTest, SendMgmtFrameMcsSupported) {
  WiphyFeatures wiphy_features;
  wiphy_features.supports_tx_mgmt_frame_mcs = true;
  SetUp(wiphy_features);

  EXPECT_CALL(*netlink_utils_,
      SendMgmtFrame(kTestInterfaceIndex,
          vector<uint8_t>(std::begin(kTestFrame), std::end(kTestFrame)),
          kMcs, _))
    .WillOnce([](uint32_t interface_index, const vector<uint8_t>& frame,
        int32_t mcs, uint64_t* out_cookie) {
      *out_cookie = kCookie;
      return true;
    });

  EXPECT_CALL(*send_mgmt_frame_event_, OnAck(_));

  client_interface_->SendMgmtFrame(
      vector<uint8_t>(std::begin(kTestFrame), std::end(kTestFrame)),
      send_mgmt_frame_event_, kMcs);
  frame_tx_status_event_handler_(kCookie, true);
}

/**
 * Transmitted frame was not ACKed.
 */
TEST_F(ClientInterfaceImplTest, SendMgmtFrameNotAcked) {
  EXPECT_CALL(*netlink_utils_,
      SendMgmtFrame(kTestInterfaceIndex,
          vector<uint8_t>(std::begin(kTestFrame), std::end(kTestFrame)),
          kAutoMcs, _))
    .WillOnce([](uint32_t interface_index, const vector<uint8_t>& frame,
        int32_t mcs, uint64_t* out_cookie) {
      *out_cookie = kCookie;
      return true;
    });

  EXPECT_CALL(*send_mgmt_frame_event_,
      OnFailure(send_mgmt_frame_event_->SEND_MGMT_FRAME_ERROR_NO_ACK));

  client_interface_->SendMgmtFrame(
      vector<uint8_t>(std::begin(kTestFrame), std::end(kTestFrame)),
      send_mgmt_frame_event_, kAutoMcs);
  frame_tx_status_event_handler_(kCookie, false);
}

/**
 * Transmission failed due to unknown NL80211 error.
 */
TEST_F(ClientInterfaceImplTest, SendMgmtFrameUnknownError) {
  EXPECT_CALL(*netlink_utils_,
      SendMgmtFrame(kTestInterfaceIndex,
        vector<uint8_t>(std::begin(kTestFrame), std::end(kTestFrame)), kAutoMcs, _))
    .WillOnce([](uint32_t interface_index, const vector<uint8_t>& frame,
        int32_t mcs, uint64_t* out_cookie) {
      return false;
    });

  EXPECT_CALL(*send_mgmt_frame_event_,
      OnFailure(send_mgmt_frame_event_->SEND_MGMT_FRAME_ERROR_UNKNOWN));

  client_interface_->SendMgmtFrame(
      vector<uint8_t>(std::begin(kTestFrame), std::end(kTestFrame)),
      send_mgmt_frame_event_, kAutoMcs);
}

/**
 * Received cookie was different than expected; No callback should be triggered.
 */
TEST_F(ClientInterfaceImplTest, SendMgmtFrameWrongCookie) {
  EXPECT_CALL(*netlink_utils_,
      SendMgmtFrame(kTestInterfaceIndex,
          vector<uint8_t>(std::begin(kTestFrame), std::end(kTestFrame)),
          kAutoMcs, _))
    .WillOnce([](uint32_t interface_index, const vector<uint8_t>& frame,
        int32_t mcs, uint64_t* out_cookie) {
      *out_cookie = kCookie;
      return true;
    });

  client_interface_->SendMgmtFrame(
      vector<uint8_t>(std::begin(kTestFrame), std::end(kTestFrame)),
      send_mgmt_frame_event_, kAutoMcs);
  frame_tx_status_event_handler_(
      kCookie + 1, // wrong cookie
      false);

  // StrictMock<MockISendMgmtFrameEvent> will fail if any unexpected method is
  // called, guaranteeing no interaction with the callback.
}

/**
 * frame_tx_status_event_handler_ triggered even though no transmission is in
 * progress. No callback should be triggered.
 */
TEST_F(ClientInterfaceImplTest, SendMgmtFrameNoTxCallbackTriggered) {
  EXPECT_CALL(*netlink_utils_,
      SendMgmtFrame(kTestInterfaceIndex,
          vector<uint8_t>(std::begin(kTestFrame), std::end(kTestFrame)),
          kAutoMcs, _))
    .WillOnce([](uint32_t interface_index, const vector<uint8_t>& frame,
        int32_t mcs, uint64_t* out_cookie) {
      *out_cookie = kCookie;
      return true;
    });

  EXPECT_CALL(*send_mgmt_frame_event_,
      OnFailure(send_mgmt_frame_event_->SEND_MGMT_FRAME_ERROR_NO_ACK));

  client_interface_->SendMgmtFrame(
      vector<uint8_t>(std::begin(kTestFrame), std::end(kTestFrame)),
      send_mgmt_frame_event_, kAutoMcs);
  frame_tx_status_event_handler_(kCookie, false);

  // transmission has finished here.

  // Now send another Tx status event.
  frame_tx_status_event_handler_(kCookie + 1, false);
  // StrictMock<MockISendMgmtFrameEvent> will fail if any unexpected method is
  // called, guaranteeing no more interaction with the callback.
}

/**
 * Second transmission was started even though no Tx Status event was received
 * for the first transmission. Should discard first transmission, and second
 * transmission should work normally.
 *
 * Since timeout of this SendMgmtFrame() is managed by framework, and framework
 * does not notify wificond when the call times out, wificond should still work
 * when a second call is made, even though it seems as though the first call is
 * still incomplete.
 */
TEST_F(ClientInterfaceImplTest, SendMgmtFrameSecondTxWhileFirstTxIncomplete) {
  EXPECT_CALL(*netlink_utils_,
      SendMgmtFrame(kTestInterfaceIndex,
          vector<uint8_t>(std::begin(kTestFrame), std::end(kTestFrame)),
          kAutoMcs, _))
    .WillOnce([](uint32_t interface_index, const vector<uint8_t>& frame,
        int32_t mcs, uint64_t* out_cookie) {
      *out_cookie = kCookie;
      return true;
    })
    .WillOnce([](uint32_t interface_index, const vector<uint8_t>& frame,
        int32_t mcs, uint64_t* out_cookie) {
      *out_cookie = kCookie + 1;
      return true;
    });

  // first transmission; no tx status
  client_interface_->SendMgmtFrame(
      vector<uint8_t>(std::begin(kTestFrame), std::end(kTestFrame)),
      send_mgmt_frame_event_, kAutoMcs);

  sp<StrictMock<MockISendMgmtFrameEvent>> send_mgmt_frame_event2{
      new StrictMock<MockISendMgmtFrameEvent>()};

  EXPECT_CALL(*send_mgmt_frame_event2,
      OnFailure(send_mgmt_frame_event_->SEND_MGMT_FRAME_ERROR_NO_ACK));

  // second transmission; yes tx status
  client_interface_->SendMgmtFrame(
      vector<uint8_t>(std::begin(kTestFrame), std::end(kTestFrame)),
      send_mgmt_frame_event2, kAutoMcs);
  frame_tx_status_event_handler_(kCookie + 1, false);

  // now trigger tx status for first call; nothing should happen (implicitly
  // verified by StrictMock).
  frame_tx_status_event_handler_(kCookie, false);
}

/**
 * Tests that internal state is reset correctly between calls by performing
 * two transmissions in sequence.
 */
TEST_F(ClientInterfaceImplTest, SendMgmtFrameInternalStateResetBetweenCalls) {
  EXPECT_CALL(*netlink_utils_,
      SendMgmtFrame(kTestInterfaceIndex,
          vector<uint8_t>(std::begin(kTestFrame), std::end(kTestFrame)),
          kAutoMcs, _))
    .WillOnce([](uint32_t interface_index, const vector<uint8_t>& frame,
        int32_t mcs, uint64_t* out_cookie) {
      *out_cookie = kCookie;
      return true;
    });

  EXPECT_CALL(*send_mgmt_frame_event_, OnAck(_));

  client_interface_->SendMgmtFrame(
      vector<uint8_t>(std::begin(kTestFrame), std::end(kTestFrame)),
      send_mgmt_frame_event_, kAutoMcs);
  frame_tx_status_event_handler_(kCookie, true);

  Mock::VerifyAndClearExpectations(netlink_utils_.get());
  Mock::VerifyAndClearExpectations(send_mgmt_frame_event_.get());

  uint64_t new_cookie = kCookie + 1;

  EXPECT_CALL(*netlink_utils_,
      SendMgmtFrame(kTestInterfaceIndex,
          vector<uint8_t>(std::begin(kTestFrame), std::end(kTestFrame)),
          kAutoMcs, _))
    .WillOnce([new_cookie](uint32_t interface_index,
        const vector<uint8_t>& frame, int32_t mcs, uint64_t* out_cookie) {
      *out_cookie = new_cookie;
      return true;
    });

  EXPECT_CALL(*send_mgmt_frame_event_,
      OnFailure(send_mgmt_frame_event_->SEND_MGMT_FRAME_ERROR_NO_ACK));

  client_interface_->SendMgmtFrame(
      vector<uint8_t>(std::begin(kTestFrame), std::end(kTestFrame)),
      send_mgmt_frame_event_, kAutoMcs);
  frame_tx_status_event_handler_(new_cookie, false);
}

}  // namespace wificond
}  // namespace android
