// Copyright 2021 The Chromium OS 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 "typecd/udev_monitor.h"

#include <base/logging.h>
#include <brillo/udev/mock_udev.h>
#include <brillo/udev/mock_udev_device.h>
#include <brillo/udev/mock_udev_enumerate.h>
#include <brillo/udev/mock_udev_list_entry.h>
#include <brillo/udev/mock_udev_monitor.h>
#include "fuzzer/FuzzedDataProvider.h"

#include "typecd/test_constants.h"

using testing::_;
using testing::ByMove;
using testing::Return;
using testing::StrEq;

namespace {

// Stub TypecObserver so that UdevMonitor has some callbacks to use.
class FuzzerTypecObserver : public typecd::UdevMonitor::TypecObserver {
 public:
  void OnPortAddedOrRemoved(const base::FilePath& path,
                            int port_num,
                            bool added) override{};
  void OnPartnerAddedOrRemoved(const base::FilePath& path,
                               int port_num,
                               bool added) override{};
  void OnPartnerAltModeAddedOrRemoved(const base::FilePath& path,
                                      int port_num,
                                      bool added) override{};
  void OnCableAddedOrRemoved(const base::FilePath& path,
                             int port_num,
                             bool added) override{};
  void OnCablePlugAdded(const base::FilePath& path, int port_num) override{};
  void OnCableAltModeAdded(const base::FilePath& path, int port_num) override{};
  void OnPartnerChanged(int port_num) override{};
  void OnPortChanged(int port_num) override{};
};

// Stub UsbObserver so that UdevMonitor has some callbacks to use.
class FuzzerUsbObserver : public typecd::UdevMonitor::UsbObserver {
 public:
  void OnDeviceAddedOrRemoved(const base::FilePath& path,
                              bool added) override{};
};

}  // namespace

namespace typecd {

// Setup/Teardown code adapted from UdevMonitorTest.
class UdevMonitorFuzzer {
 public:
  UdevMonitorFuzzer() {
    typec_observer_ = std::make_unique<FuzzerTypecObserver>();
    usb_observer_ = std::make_unique<FuzzerUsbObserver>();

    monitor_ = std::make_unique<typecd::UdevMonitor>();
    monitor_->AddTypecObserver(typec_observer_.get());
    monitor_->AddUsbObserver(usb_observer_.get());
  }

  ~UdevMonitorFuzzer() {
    monitor_.reset();
    typec_observer_.reset();
    usb_observer_.reset();
  }

  void SetUdev(std::unique_ptr<brillo::MockUdev> udev) {
    monitor_->SetUdev(std::move(udev));
  }

  void CallScanDevices() { monitor_->ScanDevices(); }

 private:
  std::unique_ptr<FuzzerTypecObserver> typec_observer_;
  std::unique_ptr<FuzzerUsbObserver> usb_observer_;
  std::unique_ptr<typecd::UdevMonitor> monitor_;
};

}  // namespace typecd

class Environment {
 public:
  Environment() { logging::SetMinLogLevel(logging::LOGGING_ERROR); }
};

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
  static Environment env;
  FuzzedDataProvider data_provider(data, size);
  typecd::UdevMonitorFuzzer fuzzer;

  // We should at least have 2 1 character length strings.
  if (size < 2)
    return 0;

  auto entry2_str = data_provider.ConsumeRandomLengthString(size / 2);
  auto list_entry2 = std::make_unique<brillo::MockUdevListEntry>();
  EXPECT_CALL(*list_entry2, GetName()).WillOnce(Return(entry2_str.c_str()));
  EXPECT_CALL(*list_entry2, GetNext()).WillOnce(Return(ByMove(nullptr)));

  auto entry1_str = data_provider.ConsumeRandomLengthString(size / 2);
  auto list_entry1 = std::make_unique<brillo::MockUdevListEntry>();
  EXPECT_CALL(*list_entry1, GetName()).WillOnce(Return(entry1_str.c_str()));
  EXPECT_CALL(*list_entry1, GetNext())
      .WillOnce(Return(ByMove(std::move(list_entry2))));

  // Ensuring that when we add the "typec" subsystem matcher to the udev
  // monitor, we don't fail.
  auto enumerate = std::make_unique<brillo::MockUdevEnumerate>();
  EXPECT_CALL(*enumerate, AddMatchSubsystem(StrEq(typecd::kUsbSubsystem)))
      .WillOnce(Return(true));
  EXPECT_CALL(*enumerate, AddMatchSubsystem(StrEq(typecd::kTypeCSubsystem)))
      .WillOnce(Return(true));
  EXPECT_CALL(*enumerate, ScanDevices()).WillOnce(Return(true));
  EXPECT_CALL(*enumerate, GetListEntry())
      .WillOnce(Return(ByMove(std::move(list_entry1))));

  auto udev = std::make_unique<brillo::MockUdev>();
  EXPECT_CALL(*udev, CreateEnumerate())
      .WillOnce(Return(ByMove(std::move(enumerate))));

  fuzzer.SetUdev(std::move(udev));
  fuzzer.CallScanDevices();

  return 0;
}
