/*
 * Copyright (C) 2017, 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 <vector>

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

#include "wificond/scanning/offload/offload_scan_utils.h"
#include "wificond/scanning/scanner_impl.h"
#include "wificond/tests/mock_client_interface_impl.h"
#include "wificond/tests/mock_netlink_manager.h"
#include "wificond/tests/mock_netlink_utils.h"
#include "wificond/tests/mock_offload_scan_callback_interface_impl.h"
#include "wificond/tests/mock_offload_scan_manager.h"
#include "wificond/tests/mock_offload_service_utils.h"
#include "wificond/tests/mock_scan_utils.h"
#include "wificond/tests/offload_test_utils.h"

using ::android::binder::Status;
using ::android::wifi_system::MockInterfaceTool;
using ::android::wifi_system::MockSupplicantManager;
using ::com::android::server::wifi::wificond::SingleScanSettings;
using ::com::android::server::wifi::wificond::PnoSettings;
using ::com::android::server::wifi::wificond::NativeScanResult;
using android::hardware::wifi::offload::V1_0::ScanResult;
using ::testing::Invoke;
using ::testing::NiceMock;
using ::testing::Return;
using ::testing::_;
using std::shared_ptr;
using std::unique_ptr;
using std::vector;

using namespace std::placeholders;

namespace android {
namespace wificond {

namespace {

constexpr uint32_t kFakeInterfaceIndex = 12;
constexpr uint32_t kFakeWiphyIndex = 5;
constexpr uint32_t kFakeScanIntervalMs = 10000;

// This is a helper function to mock the behavior of ScanUtils::Scan()
// when we expect a error code.
// |interface_index_ignored|, |request_random_mac_ignored|, |ssids_ignored|,
// |freqs_ignored|, |error_code| are mapped to existing parameters of ScanUtils::Scan().
// |mock_error_code| is a additional parameter used for specifying expected error code.
bool ReturnErrorCodeForScanRequest(
    int mock_error_code,
    uint32_t interface_index_ignored,
    bool request_random_mac_ignored,
    const std::vector<std::vector<uint8_t>>& ssids_ignored,
    const std::vector<uint32_t>& freqs_ignored,
    int* error_code) {
  *error_code = mock_error_code;
  // Returing false because this helper function is used for failure case.
  return false;
}

bool CaptureSchedScanIntervalSetting(
    uint32_t /* interface_index */,
    const SchedScanIntervalSetting&  interval_setting,
    int32_t /* rssi_threshold */,
    bool /* request_random_mac */,
    const  std::vector<std::vector<uint8_t>>& /* scan_ssids */,
    const std::vector<std::vector<uint8_t>>& /* match_ssids */,
    const  std::vector<uint32_t>& /* freqs */,
    int* /* error_code */,
    SchedScanIntervalSetting* out_interval_setting) {
  *out_interval_setting = interval_setting;
  return true;
}

bool ReturnOffloadScanResults(
    std::vector<NativeScanResult>* native_scan_results_,
    const std::vector<ScanResult>& offload_scan_results) {
  return OffloadScanUtils::convertToNativeScanResults(offload_scan_results,
                                                      native_scan_results_);
}

bool ReturnNetlinkScanResults(
    uint32_t interface_index,
    std::vector<NativeScanResult>* native_scan_results_,
    const std::vector<ScanResult>& offload_scan_results) {
  return OffloadScanUtils::convertToNativeScanResults(offload_scan_results,
                                                      native_scan_results_);
}

}  // namespace

class ScannerTest : public ::testing::Test {
 protected:
  void SetUp() override {
    ON_CALL(*offload_service_utils_, GetOffloadScanManager(_, _))
        .WillByDefault(Return(offload_scan_manager_));
    ON_CALL(*offload_service_utils_, GetOffloadScanCallbackInterface(_))
        .WillByDefault(Return(offload_scan_callback_interface_));
    dummy_scan_results_ = OffloadTestUtils::createOffloadScanResults();
  }

  void TearDown() override { dummy_scan_results_.clear(); }

  unique_ptr<ScannerImpl> scanner_impl_;
  NiceMock<MockNetlinkManager> netlink_manager_;
  NiceMock<MockNetlinkUtils> netlink_utils_{&netlink_manager_};
  NiceMock<MockScanUtils> scan_utils_{&netlink_manager_};
  NiceMock<MockInterfaceTool> if_tool_;
  NiceMock<MockSupplicantManager> supplicant_manager_;
  NiceMock<MockClientInterfaceImpl> client_interface_impl_{
      &if_tool_, &supplicant_manager_, &netlink_utils_, &scan_utils_};
  shared_ptr<NiceMock<MockOffloadServiceUtils>> offload_service_utils_{
      new NiceMock<MockOffloadServiceUtils>()};
  shared_ptr<NiceMock<MockOffloadScanCallbackInterfaceImpl>>
      offload_scan_callback_interface_{
          new NiceMock<MockOffloadScanCallbackInterfaceImpl>(
              scanner_impl_.get())};
  std::shared_ptr<NiceMock<MockOffloadScanManager>> offload_scan_manager_{
      new NiceMock<MockOffloadScanManager>(offload_service_utils_,
                                           offload_scan_callback_interface_)};
  ScanCapabilities scan_capabilities_;
  WiphyFeatures wiphy_features_;
  std::vector<ScanResult> dummy_scan_results_;
};

TEST_F(ScannerTest, TestSingleScan) {
  EXPECT_CALL(scan_utils_, Scan(_, _, _, _, _)).WillOnce(Return(true));
  bool success = false;
  scanner_impl_.reset(new ScannerImpl(kFakeWiphyIndex, kFakeInterfaceIndex,
                                      scan_capabilities_, wiphy_features_,
                                      &client_interface_impl_, &netlink_utils_,
                                      &scan_utils_, offload_service_utils_));
  EXPECT_TRUE(scanner_impl_->scan(SingleScanSettings(), &success).isOk());
  EXPECT_TRUE(success);
}

TEST_F(ScannerTest, TestSingleScanFailure) {
  scanner_impl_.reset(new ScannerImpl(kFakeWiphyIndex, kFakeInterfaceIndex,
                                      scan_capabilities_, wiphy_features_,
                                      &client_interface_impl_, &netlink_utils_,
                                      &scan_utils_, offload_service_utils_));
  EXPECT_CALL(
      scan_utils_,
      Scan(_, _, _, _, _)).
          WillOnce(Invoke(bind(
              ReturnErrorCodeForScanRequest, EBUSY, _1, _2, _3, _4, _5)));

  bool success = false;
  EXPECT_TRUE(scanner_impl_->scan(SingleScanSettings(), &success).isOk());
  EXPECT_FALSE(success);
}

TEST_F(ScannerTest, TestProcessAbortsOnScanReturningNoDeviceError) {
  scanner_impl_.reset(new ScannerImpl(kFakeWiphyIndex, kFakeInterfaceIndex,
                                      scan_capabilities_, wiphy_features_,
                                      &client_interface_impl_, &netlink_utils_,
                                      &scan_utils_, offload_service_utils_));
  ON_CALL(
      scan_utils_,
      Scan(_, _, _, _, _)).
          WillByDefault(Invoke(bind(
              ReturnErrorCodeForScanRequest, ENODEV, _1, _2, _3, _4, _5)));

  bool success_ignored;
  EXPECT_DEATH(scanner_impl_->scan(SingleScanSettings(), &success_ignored),
               "Driver is in a bad state*");
}

TEST_F(ScannerTest, TestAbortScan) {
  bool single_scan_success = false;
  scanner_impl_.reset(new ScannerImpl(kFakeWiphyIndex, kFakeInterfaceIndex,
                                      scan_capabilities_, wiphy_features_,
                                      &client_interface_impl_, &netlink_utils_,
                                      &scan_utils_, offload_service_utils_));
  EXPECT_CALL(scan_utils_, Scan(_, _, _, _, _)).WillOnce(Return(true));
  EXPECT_TRUE(
      scanner_impl_->scan(SingleScanSettings(), &single_scan_success).isOk());
  EXPECT_TRUE(single_scan_success);

  EXPECT_CALL(scan_utils_, AbortScan(_));
  EXPECT_TRUE(scanner_impl_->abortScan().isOk());
}

TEST_F(ScannerTest, TestAbortScanNotIssuedIfNoOngoingScan) {
  scanner_impl_.reset(new ScannerImpl(kFakeWiphyIndex, kFakeInterfaceIndex,
                                      scan_capabilities_, wiphy_features_,
                                      &client_interface_impl_, &netlink_utils_,
                                      &scan_utils_, offload_service_utils_));
  EXPECT_CALL(scan_utils_, AbortScan(_)).Times(0);
  EXPECT_TRUE(scanner_impl_->abortScan().isOk());
}

TEST_F(ScannerTest, TestGetScanResults) {
  vector<NativeScanResult> scan_results;
  scanner_impl_.reset(new ScannerImpl(kFakeWiphyIndex, kFakeInterfaceIndex,
                                      scan_capabilities_, wiphy_features_,
                                      &client_interface_impl_, &netlink_utils_,
                                      &scan_utils_, offload_service_utils_));
  EXPECT_CALL(scan_utils_, GetScanResult(_, _)).WillOnce(Return(true));
  EXPECT_TRUE(scanner_impl_->getScanResults(&scan_results).isOk());
}

TEST_F(ScannerTest, TestStartPnoScanViaNetlink) {
  bool success = false;
  EXPECT_CALL(*offload_service_utils_, IsOffloadScanSupported())
      .Times(1)
      .WillRepeatedly(Return(false));
  scanner_impl_.reset(new ScannerImpl(kFakeWiphyIndex, kFakeInterfaceIndex,
                                      scan_capabilities_, wiphy_features_,
                                      &client_interface_impl_, &netlink_utils_,
                                      &scan_utils_, offload_service_utils_));
  EXPECT_CALL(scan_utils_, StartScheduledScan(_, _, _, _, _, _, _, _)).
              WillOnce(Return(true));
  EXPECT_TRUE(scanner_impl_->startPnoScan(PnoSettings(), &success).isOk());
  EXPECT_TRUE(success);
}

TEST_F(ScannerTest, TestStopPnoScanViaNetlink) {
  bool success = false;
  EXPECT_CALL(*offload_service_utils_, IsOffloadScanSupported())
      .Times(1)
      .WillRepeatedly(Return(false));
  scanner_impl_.reset(new ScannerImpl(kFakeWiphyIndex, kFakeInterfaceIndex,
                                      scan_capabilities_, wiphy_features_,
                                      &client_interface_impl_, &netlink_utils_,
                                      &scan_utils_, offload_service_utils_));
  // StopScheduledScan() will be called no matter if there is an ongoing
  // scheduled scan or not. This is for making the system more robust.
  EXPECT_CALL(scan_utils_, StopScheduledScan(_)).WillOnce(Return(true));
  EXPECT_TRUE(scanner_impl_->stopPnoScan(&success).isOk());
  EXPECT_TRUE(success);
}

TEST_F(ScannerTest, TestStartScanOverOffload) {
  bool success = false;
  EXPECT_CALL(*offload_service_utils_, IsOffloadScanSupported())
      .Times(1)
      .WillRepeatedly(Return(true));
  EXPECT_CALL(*offload_scan_manager_, startScan(_, _, _, _, _, _, _))
      .Times(1)
      .WillRepeatedly(Return(true));
  EXPECT_CALL(*offload_scan_manager_, stopScan(_))
      .Times(1)
      .WillRepeatedly(Return(true));
  scanner_impl_.reset(new ScannerImpl(kFakeWiphyIndex, kFakeInterfaceIndex,
                                      scan_capabilities_, wiphy_features_,
                                      &client_interface_impl_, &netlink_utils_,
                                      &scan_utils_, offload_service_utils_));
  scanner_impl_->startPnoScan(PnoSettings(), &success);
  EXPECT_TRUE(success);
  scanner_impl_->stopPnoScan(&success);
  EXPECT_TRUE(success);
}

TEST_F(ScannerTest, TestStartScanOverNetlinkFallback) {
  bool success = false;
  ON_CALL(*offload_service_utils_, IsOffloadScanSupported())
      .WillByDefault(Return(true));
  scanner_impl_.reset(new ScannerImpl(kFakeWiphyIndex, kFakeInterfaceIndex,
                                      scan_capabilities_, wiphy_features_,
                                      &client_interface_impl_, &netlink_utils_,
                                      &scan_utils_, offload_service_utils_));
  EXPECT_CALL(*offload_scan_manager_, startScan(_, _, _, _, _, _, _))
      .WillOnce(Return(false));
  EXPECT_CALL(*offload_scan_manager_, stopScan(_)).Times(0);
  EXPECT_CALL(scan_utils_, StartScheduledScan(_, _, _, _, _, _, _, _))
      .WillOnce(Return(true));
  EXPECT_CALL(scan_utils_, StopScheduledScan(_)).WillOnce(Return(true));
  EXPECT_TRUE(scanner_impl_->startPnoScan(PnoSettings(), &success).isOk());
  EXPECT_TRUE(success == true);
  scanner_impl_->stopPnoScan(&success);
  EXPECT_TRUE(success);
}

TEST_F(ScannerTest, TestAsyncErrorOverOffload) {
  bool success = false;
  EXPECT_CALL(*offload_service_utils_, IsOffloadScanSupported())
      .Times(1)
      .WillRepeatedly(Return(true));
  EXPECT_CALL(*offload_scan_manager_, startScan(_, _, _, _, _, _, _))
      .Times(1)
      .WillRepeatedly(Return(true));
  EXPECT_CALL(*offload_scan_manager_, stopScan(_))
      .Times(1)
      .WillRepeatedly(Return(true));
  scanner_impl_.reset(new ScannerImpl(kFakeWiphyIndex, kFakeInterfaceIndex,
                                      scan_capabilities_, wiphy_features_,
                                      &client_interface_impl_, &netlink_utils_,
                                      &scan_utils_, offload_service_utils_));
  EXPECT_CALL(scan_utils_, StartScheduledScan(_, _, _, _, _, _, _, _))
      .WillOnce(Return(true));
  EXPECT_CALL(scan_utils_, StopScheduledScan(_)).WillOnce(Return(true));
  scanner_impl_->startPnoScan(PnoSettings(), &success);
  EXPECT_TRUE(success);
  scanner_impl_->OnOffloadError(
      OffloadScanCallbackInterface::AsyncErrorReason::REMOTE_FAILURE);
  scanner_impl_->stopPnoScan(&success);
  EXPECT_TRUE(success);
}

TEST_F(ScannerTest, TestGetScanResultsFromOffload) {
  bool success = false;
  EXPECT_CALL(*offload_service_utils_, IsOffloadScanSupported())
      .Times(1)
      .WillRepeatedly(Return(true));
  EXPECT_CALL(*offload_scan_manager_, startScan(_, _, _, _, _, _, _))
      .Times(1)
      .WillRepeatedly(Return(true));
  EXPECT_CALL(*offload_scan_manager_, getScanResults(_))
      .Times(1)
      .WillOnce(
          Invoke(bind(ReturnOffloadScanResults, _1, dummy_scan_results_)));
  EXPECT_CALL(*offload_scan_manager_, stopScan(_))
      .Times(1)
      .WillRepeatedly(Return(true));
  scanner_impl_.reset(new ScannerImpl(kFakeWiphyIndex, kFakeInterfaceIndex,
                                      scan_capabilities_, wiphy_features_,
                                      &client_interface_impl_, &netlink_utils_,
                                      &scan_utils_, offload_service_utils_));
  scanner_impl_->startPnoScan(PnoSettings(), &success);
  EXPECT_TRUE(success);
  scanner_impl_->OnOffloadScanResult();
  std::vector<NativeScanResult> scan_results;
  EXPECT_TRUE(scanner_impl_->getPnoScanResults(&scan_results).isOk());
  EXPECT_FALSE(scan_results.empty());
  scanner_impl_->stopPnoScan(&success);
  EXPECT_TRUE(success);
}

TEST_F(ScannerTest, TestGetScanResultsWhenOffloadFails) {
  bool success = false;
  EXPECT_CALL(*offload_service_utils_, IsOffloadScanSupported())
      .Times(1)
      .WillRepeatedly(Return(true));
  EXPECT_CALL(*offload_scan_manager_, startScan(_, _, _, _, _, _, _))
      .Times(1)
      .WillRepeatedly(Return(true));
  EXPECT_CALL(*offload_scan_manager_, stopScan(_))
      .Times(1)
      .WillRepeatedly(Return(true));
  EXPECT_CALL(*offload_scan_manager_, getScanResults(_)).Times(0);
  EXPECT_CALL(scan_utils_, GetScanResult(_, _))
      .Times(1)
      .WillOnce(
          Invoke(bind(ReturnNetlinkScanResults, _1, _2, dummy_scan_results_)));
  scanner_impl_.reset(new ScannerImpl(kFakeWiphyIndex, kFakeInterfaceIndex,
                                      scan_capabilities_, wiphy_features_,
                                      &client_interface_impl_, &netlink_utils_,
                                      &scan_utils_, offload_service_utils_));
  EXPECT_CALL(scan_utils_, StartScheduledScan(_, _, _, _, _, _, _, _))
      .WillOnce(Return(true));
  EXPECT_CALL(scan_utils_, StopScheduledScan(_)).WillOnce(Return(true));
  EXPECT_TRUE(scanner_impl_->startPnoScan(PnoSettings(), &success).isOk());
  EXPECT_TRUE(success);
  scanner_impl_->OnOffloadError(
      OffloadScanCallbackInterface::AsyncErrorReason::REMOTE_FAILURE);
  std::vector<NativeScanResult> scan_results;
  EXPECT_TRUE(scanner_impl_->getPnoScanResults(&scan_results).isOk());
  EXPECT_FALSE(scan_results.empty());
  scanner_impl_->stopPnoScan(&success);
  EXPECT_TRUE(success);
}

TEST_F(ScannerTest, TestGenerateScanPlansIfDeviceSupports) {
  ScanCapabilities scan_capabilities_scan_plan_supported(
      0 /* max_num_scan_ssids */,
      0 /* max_num_sched_scan_ssids */,
      0 /* max_match_sets */,
      // Parameters above are not related to this test.
      2 /* 1 plan for finite repeated scan and 1 plan for ininfite scan loop */,
      kFakeScanIntervalMs * PnoSettings::kSlowScanIntervalMultiplier / 1000,
      PnoSettings::kFastScanIterations);
  ScannerImpl scanner(
      kFakeWiphyIndex, kFakeInterfaceIndex,
      scan_capabilities_scan_plan_supported, wiphy_features_,
      &client_interface_impl_,
      &netlink_utils_, &scan_utils_, offload_service_utils_);

  PnoSettings pno_settings;
  pno_settings.interval_ms_ = kFakeScanIntervalMs;

  SchedScanIntervalSetting interval_setting;
  EXPECT_CALL(
      scan_utils_,
      StartScheduledScan(_, _, _, _, _, _, _, _)).
              WillOnce(Invoke(bind(
                  CaptureSchedScanIntervalSetting,
                  _1, _2, _3, _4, _5, _6, _7, _8, &interval_setting)));

  bool success_ignored = 0;
  EXPECT_TRUE(scanner.startPnoScan(pno_settings, &success_ignored).isOk());
  /* 1 plan for finite repeated scan */
  EXPECT_EQ(1U, interval_setting.plans.size());
  EXPECT_EQ(kFakeScanIntervalMs * PnoSettings::kSlowScanIntervalMultiplier,
            interval_setting.final_interval_ms);
}

TEST_F(ScannerTest, TestGenerateSingleIntervalIfDeviceDoesNotSupportScanPlan) {
  ScanCapabilities scan_capabilities_no_scan_plan_support(
      0 /* max_num_scan_ssids */,
      0 /* max_num_sched_scan_ssids */,
      0 /* max_match_sets */,
      // Parameters above are not related to this test.
      0 /* max_num_scan_plans */,
      0 /* max_scan_plan_interval */,
      0 /* max_scan_plan_iterations */);
  ScannerImpl scanner(
      kFakeWiphyIndex, kFakeInterfaceIndex,
      scan_capabilities_no_scan_plan_support, wiphy_features_,
      &client_interface_impl_,
      &netlink_utils_, &scan_utils_, offload_service_utils_);
  PnoSettings pno_settings;
  pno_settings.interval_ms_ = kFakeScanIntervalMs;

  SchedScanIntervalSetting interval_setting;
  EXPECT_CALL(
      scan_utils_,
      StartScheduledScan(_, _, _, _, _, _, _, _)).
              WillOnce(Invoke(bind(
                  CaptureSchedScanIntervalSetting,
                  _1, _2, _3, _4, _5, _6, _7, _8, &interval_setting)));

  bool success_ignored = 0;
  EXPECT_TRUE(scanner.startPnoScan(pno_settings, &success_ignored).isOk());

  EXPECT_EQ(0U, interval_setting.plans.size());
  EXPECT_EQ(kFakeScanIntervalMs, interval_setting.final_interval_ms);
}

}  // namespace wificond
}  // namespace android
