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

#ifndef MIDIS_SEQ_HANDLER_H_
#define MIDIS_SEQ_HANDLER_H_

#include <memory>

#include <base/files/file_descriptor_watcher_posix.h>
#include <base/memory/weak_ptr.h>
#include <gtest/gtest_prod.h>

#include "midis/device.h"
#include "midis/device_tracker.h"

namespace midis {

class DeviceTracker;

// Class to handle all interactions with the ALSA sequencer interface.
// NOTE: The term "input" refers to data received *from* the MIDI H/W and
// external clients that are registered to the ALSA sequencer interfance. The
// term "output" refers to data that a client of midis write *to* MIDI H/W and
// external clients.
class SeqHandler {
 public:
  using AddDeviceCallback =
      base::RepeatingCallback<void(std::unique_ptr<Device>)>;
  using RemoveDeviceCallback =
      base::RepeatingCallback<void(uint32_t, uint32_t)>;
  using HandleReceiveDataCallback = base::RepeatingCallback<void(
      uint32_t, uint32_t, uint32_t, const char*, size_t)>;
  using IsDevicePresentCallback =
      base::RepeatingCallback<bool(uint32_t, uint32_t)>;
  using IsPortPresentCallback =
      base::RepeatingCallback<bool(uint32_t, uint32_t, uint32_t)>;

  struct SeqDeleter {
    void operator()(snd_seq_t* seq) const { snd_seq_close(seq); }
  };

  struct MidiEventDeleter {
    void operator()(snd_midi_event_t* coder) const {
      snd_midi_event_free(coder);
    }
  };

  using ScopedMidiEventPtr =
      std::unique_ptr<snd_midi_event_t, MidiEventDeleter>;
  using ScopedSeqPtr = std::unique_ptr<snd_seq_t, SeqDeleter>;

  SeqHandler(AddDeviceCallback add_device_cb,
             RemoveDeviceCallback remove_device_cb,
             HandleReceiveDataCallback handle_rx_data_cb,
             IsDevicePresentCallback is_device_present_cb,
             IsPortPresentCallback is_port_present_cb);

  virtual ~SeqHandler() = default;

  // Initializes the ALSA seq interface. Creates client handles for input and
  // output, as well create an input port to receive messages (announce as
  // well as MIDI data) from ALSA seq. Also starts off the file watcher which
  // watches for events on the input port.
  bool InitSeq();
  void ProcessAlsaClientFd();

  // Creates a Device object and runs the necessary callback to register that
  // object with DeviceTracker, stored in |add_device_cb_|
  virtual void AddSeqDevice(uint32_t device_id);

  // At present, we don't support hotplugging of individual ports in devices.
  // so, we enumerate all the available ports in AddAlsaDevice().
  // This function is here merely to handle MIDI events associated with any
  // port being added or removed later (and to print an error message, since
  // we don't support it yet)
  virtual void AddSeqPort(uint32_t device_id, uint32_t port_id);

  // Runs the relevant callback, stored in |remove_device_cb_|, when a MIDI H/W
  // device or external client is removed from the ALSA sequencer interface.
  virtual void RemoveSeqDevice(uint32_t device_id);

  virtual void RemoveSeqPort(uint32_t device_id, uint32_t port_id);

  // Callback to run when starting an input port (establishes a subscription,
  // and creates a relevant port on the server side, in necessary).
  // Returns true on success, false otherwise.
  bool SubscribeInPort(uint32_t device_id, uint32_t port_id);

  // Callback to run when starting an input port (establishes a subscription,
  // and creates a relevant port on the server side, in necessary).
  // Returns created seq port id success, -1 otherwise.
  int SubscribeOutPort(uint32_t device_id, uint32_t port_id);

  // The following two functions undo the work of the Subscribe*Port() function,
  // for input and output ports respectively.
  void UnsubscribeInPort(uint32_t device_id, uint32_t port_id);
  void UnsubscribeOutPort(int out_port_id);

  // Encodes the bytes in a MIDI buffer into the provided |encoder|.
  bool EncodeMidiBytes(int out_port_id,
                       snd_seq_t* out_client,
                       const uint8_t* buffer,
                       size_t buffer_len,
                       snd_midi_event_t* encoder);

  // Callback to send MIDI data to the H/W. This callback is generally called by
  // a Device handler which receives MIDI data from a client (e.g ARC++). The
  // Device handler will in turn be called by a Client handler which is
  // listening for data from it's client.
  void SendMidiData(int out_port_id, const uint8_t* buffer, size_t buf_len);

  // This function processes the MIDI data received from H/W or an external
  // client, and invokes the callback |handle_rx_data_cb_| which handles the
  // data accordingly.
  virtual void ProcessMidiEvent(snd_seq_event_t* event);

  // Wrappers for functions that interact with the ALSA Sequencer interface.
  // These are kept separately, because the intention is to mock these functions
  // in unit tests.
  virtual int SndSeqEventOutputDirect(snd_seq_t* out_client,
                                      snd_seq_event_t* event);
  virtual int SndSeqEventInput(snd_seq_t* in_client, snd_seq_event_t** ev);
  virtual int SndSeqEventInputPending(snd_seq_t* in_client,
                                      int fetch_sequencer);

 protected:
  // For testing purposes.
  SeqHandler();
  SeqHandler(const SeqHandler&) = delete;
  SeqHandler& operator=(const SeqHandler&) = delete;

 private:
  friend class SeqHandlerTest;
  friend class SeqHandlerFuzzer;
  FRIEND_TEST(SeqHandlerTest, TestEncodeBytes);
  FRIEND_TEST(SeqHandlerTest, TestProcessAlsaClientFdPositive);
  FRIEND_TEST(SeqHandlerTest, TestProcessMidiEventsPositive);
  FRIEND_TEST(SeqHandlerTest, TestProcessMidiEventsNegative);

  // Enumerates all clients which are already connected to the ALSA Sequencer.
  void EnumerateExistingDevices();

  // Creates a MIDI event wrapped in a ScopedMidiEventPtr.
  static ScopedMidiEventPtr CreateMidiEvent(size_t buf_size);

  std::unique_ptr<snd_seq_t, SeqDeleter> in_client_;
  std::unique_ptr<snd_seq_t, SeqDeleter> out_client_;
  std::unique_ptr<snd_midi_event_t, MidiEventDeleter> decoder_;
  int in_client_id_;
  int out_client_id_;
  int in_port_id_;
  std::unique_ptr<pollfd> pfd_;
  std::unique_ptr<base::FileDescriptorWatcher::Controller> watcher_;

  AddDeviceCallback add_device_cb_;
  RemoveDeviceCallback remove_device_cb_;
  HandleReceiveDataCallback handle_rx_data_cb_;
  IsDevicePresentCallback is_device_present_cb_;
  IsPortPresentCallback is_port_present_cb_;
  base::WeakPtrFactory<SeqHandler> weak_factory_;
};

}  // namespace midis

#endif  // MIDIS_SEQ_HANDLER_H_
