// 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::Callback<void(std::unique_ptr<Device>)>;
  using RemoveDeviceCallback = base::Callback<void(uint32_t, uint32_t)>;
  using HandleReceiveDataCallback =
      base::Callback<void(uint32_t, uint32_t, uint32_t, const char*, size_t)>;
  using IsDevicePresentCallback = base::Callback<bool(uint32_t, uint32_t)>;
  using IsPortPresentCallback =
      base::Callback<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();

 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_;

  DISALLOW_COPY_AND_ASSIGN(SeqHandler);
};

}  // namespace midis

#endif  // MIDIS_SEQ_HANDLER_H_
