// Copyright 2018 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 "midis/seq_handler.h"

#include <string>

#include <base/bind.h>
#include <base/logging.h>

#include "midis/device.h"

namespace {

const int kFakeOutputPort = 0;
}

namespace midis {

// We don't have a real device whose callbacks we can run, so instead,
// we just create FakeCallbacks which contains stubs.
class FakeCallbacks {
 public:
  void AddDevice(std::unique_ptr<Device> device) {}
  void RemoveDevice(uint32_t card_num, uint32_t device_num) {}
  void HandleReceiveData(uint32_t card_id,
                         uint32_t device_id,
                         uint32_t port_id,
                         const char* buffer,
                         size_t buf_len) {}
  bool IsDevicePresent(uint32_t card_num, uint32_t device_num) {
    // Unused in the fuzzer, so doesn't matter.
    return true;
  }
  bool IsPortPresent(uint32_t card_num, uint32_t device_num, uint32_t port_id) {
    // Unused in the fuzzer, so doesn't matter.
    return true;
  }
};

// Running a fuzz test on the SeqHandler requires us to set certain
// private variables inside SeqHandler. To allow this to happen,
// we encapsulate the SeqHandler inside a FuzzerRunner class,
// and make FuzzerRunner a friend of SeqHandler.
class SeqHandlerFuzzer {
 public:
  void SetUpSeqHandler() {
    seq_handler_ = std::make_unique<SeqHandler>(
        base::Bind(&FakeCallbacks::AddDevice, base::Unretained(&callbacks_)),
        base::Bind(&FakeCallbacks::RemoveDevice, base::Unretained(&callbacks_)),
        base::Bind(&FakeCallbacks::HandleReceiveData,
                   base::Unretained(&callbacks_)),
        base::Bind(&FakeCallbacks::IsDevicePresent,
                   base::Unretained(&callbacks_)),
        base::Bind(&FakeCallbacks::IsPortPresent,
                   base::Unretained(&callbacks_)));

    seq_handler_->decoder_ = midis::SeqHandler::CreateMidiEvent(0);
  }

  bool SetUpOutputPort() {
    snd_seq_t* tmp_seq = nullptr;

    int err = snd_seq_open(&tmp_seq, "hw", SND_SEQ_OPEN_OUTPUT, 0);
    if (err != 0) {
      LOG(ERROR) << "snd_seq_open fails: " << snd_strerror(err);
      return false;
    }

    SeqHandler::ScopedSeqPtr out_client(tmp_seq);
    tmp_seq = nullptr;
    seq_handler_->out_client_ = std::move(out_client);
    seq_handler_->out_client_id_ =
        snd_seq_client_id(seq_handler_->out_client_.get());
    return true;
  }

  // Send arbitrary data to ProcessMidiEvent() and see what happens.
  void ProcessMidiEvent(const uint8_t* data, size_t size) {
    snd_seq_event_t event;
    size_t bytes_to_copy = sizeof(snd_seq_event_t);
    if (size < bytes_to_copy) {
      bytes_to_copy = size;
    }
    memcpy(&event, data, bytes_to_copy);
    seq_handler_->ProcessMidiEvent(&event);
  }

  void SendMidiData(const uint8_t* data, size_t size) {
    // We don't have a real output port, so we just supply a value.
    // This ALSA seq interface should fail gracefully.
    seq_handler_->SendMidiData(kFakeOutputPort, data, size);
  }

 private:
  std::unique_ptr<SeqHandler> seq_handler_;
  FakeCallbacks callbacks_;
};

struct Environment {
  Environment() { logging::SetMinLogLevel(logging::LOGGING_ERROR); }
};

Environment* env = new Environment();

}  // namespace midis

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
  midis::SeqHandlerFuzzer fuzzer;
  fuzzer.SetUpSeqHandler();
  if (!fuzzer.SetUpOutputPort()) {
    abort();
  }
  fuzzer.ProcessMidiEvent(data, size);
  fuzzer.SendMidiData(data, size);
  return 0;
}
