/*
 * BRLTTY - A background process providing access to the console screen (when in
 *          text mode) for a blind person using a refreshable braille display.
 *
 * Copyright (C) 1995-2023 by The BRLTTY Developers.
 *
 * BRLTTY comes with ABSOLUTELY NO WARRANTY.
 *
 * This is free software, placed under the terms of the
 * GNU Lesser General Public License, as published by the Free Software
 * Foundation; either version 2.1 of the License, or (at your option) any
 * later version. Please see the file LICENSE-LGPL for details.
 *
 * Web Page: http://brltty.app/
 *
 * This software is maintained by Dave Mielke <dave@mielke.cc>.
 */

#include "prologue.h"

#include <alsa/asoundlib.h>

#include "log.h"
#include "parse.h"
#include "timing.h"
#include "midi.h"

struct MidiDeviceStruct {
  snd_seq_t *sequencer;
  int port;
  int queue;
  snd_seq_queue_status_t *status;
  snd_seq_real_time_t time;
  unsigned char note;
};

#define snd_seq_control_queue snd_seq_control_queue

static int
findMidiDevice (MidiDevice *midi, int errorLevel, int *client, int *port) {
  snd_seq_client_info_t *clientInformation = malloc(snd_seq_client_info_sizeof());

  if (clientInformation) {
    memset(clientInformation, 0, snd_seq_client_info_sizeof());
    snd_seq_client_info_set_client(clientInformation, -1);

    while (snd_seq_query_next_client(midi->sequencer, clientInformation) >= 0) {
      int clientIdentifier = snd_seq_client_info_get_client(clientInformation);
      snd_seq_port_info_t *portInformation = malloc(snd_seq_port_info_sizeof());

      if (portInformation) {
        memset(portInformation, 0, snd_seq_port_info_sizeof());
        snd_seq_port_info_set_client(portInformation, clientIdentifier);
        snd_seq_port_info_set_port(portInformation, -1);

        while (snd_seq_query_next_port(midi->sequencer, portInformation) >= 0) {
          int portIdentifier = snd_seq_port_info_get_port(portInformation);
          int actualCapabilities = snd_seq_port_info_get_capability(portInformation);
          const int neededCapabilties = SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE;

          if (((actualCapabilities & neededCapabilties) == neededCapabilties) &&
              !(actualCapabilities & SND_SEQ_PORT_CAP_NO_EXPORT)) {
            *client = clientIdentifier;
            *port = portIdentifier;
            logMessage(LOG_DEBUG, "Using ALSA MIDI device: %d[%s] %d[%s]",
                       clientIdentifier, snd_seq_client_info_get_name(clientInformation),
                       portIdentifier, snd_seq_port_info_get_name(portInformation));

            free(portInformation);
            free(clientInformation);
            return 1;
          }
        }

        free(portInformation);
      } else {
        logMallocError();
      }
    }

    free(clientInformation);
  } else {
    logMallocError();
  }

  logMessage(errorLevel, "No MDII devices.");
  return 0;
}

static int
parseMidiDevice (MidiDevice *midi, int errorLevel, const char *device, int *client, int *port) {
  char **components = splitString(device, ':', NULL);

  if (components) {
    char **component = components;

    if (*component && **component) {
      const char *clientSpecifier = *component++;

      if (*component && **component) {
        const char *portSpecifier = *component++;

        if (!*component) {
          int clientIdentifier;
          int clientOk = 0;

          if (isInteger(&clientIdentifier, clientSpecifier)) {
            if ((clientIdentifier >= 0) && (clientIdentifier <= 0XFFFF)) clientOk = 1;
          } else {
            snd_seq_client_info_t *info = malloc(snd_seq_client_info_sizeof());

            if (info) {
              memset(info, 0, snd_seq_client_info_sizeof());
              snd_seq_client_info_set_client(info, -1);

              while (snd_seq_query_next_client(midi->sequencer, info) >= 0) {
                const char *name = snd_seq_client_info_get_name(info);

                if (strstr(name, clientSpecifier)) {
                  clientIdentifier = snd_seq_client_info_get_client(info);
                  clientOk = 1;
                  logMessage(LOG_INFO, "Using ALSA MIDI client: %d[%s]",
                             clientIdentifier, name);
                  break;
                }
              }

              free(info);
            } else {
              logMallocError();
            }
          }

          if (clientOk) {
            int portIdentifier;
            int portOk = 0;

            if (isInteger(&portIdentifier, portSpecifier)) {
              if ((portIdentifier >= 0) && (portIdentifier <= 0XFFFF)) portOk = 1;
            } else {
              snd_seq_port_info_t *info = malloc(snd_seq_port_info_sizeof());

              if (info) {
                memset(info, 0, snd_seq_port_info_sizeof());
                snd_seq_port_info_set_client(info, clientIdentifier);
                snd_seq_port_info_set_port(info, -1);

                while (snd_seq_query_next_port(midi->sequencer, info) >= 0) {
                  const char *name = snd_seq_port_info_get_name(info);

                  if (strstr(name, portSpecifier)) {
                    portIdentifier = snd_seq_port_info_get_port(info);
                    portOk = 1;
                    logMessage(LOG_INFO, "Using ALSA MIDI port: %d[%s]",
                               portIdentifier, name);
                    break;
                  }
                }

                free(info);
              } else {
                logMallocError();
              }
            }

            if (portOk) {
              *client = clientIdentifier;
              *port = portIdentifier;

              deallocateStrings(components);
              return 1;
            } else {
              logMessage(errorLevel, "Invalid ALSA MIDI port: %s", device);
            }
          } else {
            logMessage(errorLevel, "Invalid ALSA MIDI client: %s", device);
          }
        } else {
          logMessage(errorLevel, "Too many ALSA MIDI device components: %s", device);
        }
      } else {
        logMessage(errorLevel, "Missing ALSA MIDI port specifier: %s", device);
      }
    } else {
      logMessage(errorLevel, "Missing ALSA MIDI client specifier: %s", device);
    }

    deallocateStrings(components);
  } else {
    logMallocError();
  }

  return 0;
}

static void
updateMidiStatus (MidiDevice *midi) {
  snd_seq_get_queue_status(midi->sequencer, midi->queue, midi->status);
}

static void
startMidiTimer (MidiDevice *midi) {
  if (!midi->time.tv_sec && !midi->time.tv_nsec) {
    updateMidiStatus(midi);
    midi->time = *snd_seq_queue_status_get_real_time(midi->status);
  }
}

static void
stopMidiTimer (MidiDevice *midi) {
  midi->time.tv_sec = 0;
  midi->time.tv_nsec = 0;
}

MidiDevice *
openMidiDevice (int errorLevel, const char *device) {
  MidiDevice *midi;

  if ((midi = malloc(sizeof(*midi)))) {
    const char *sequencerName = "default";
    int result;

    if ((result = snd_seq_open(&midi->sequencer, sequencerName, SND_SEQ_OPEN_OUTPUT, 0)) >= 0) {
      snd_seq_set_client_name(midi->sequencer, PACKAGE_NAME);

      if ((midi->port = snd_seq_create_simple_port(midi->sequencer, "out0",
                                                        SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ,
                                                        SND_SEQ_PORT_TYPE_APPLICATION)) >= 0) {
        if ((midi->queue = snd_seq_alloc_queue(midi->sequencer)) >= 0) {
          if ((result = snd_seq_queue_status_malloc(&midi->status)) >= 0) {
            int client = 0;
            int port = 0;
            int deviceOk;

            if (*device) {
              deviceOk = parseMidiDevice(midi, errorLevel, device, &client, &port);
            } else {
              deviceOk = findMidiDevice(midi, errorLevel, &client, &port);
            }

            if (deviceOk) {
              logMessage(LOG_DEBUG, "Connecting to ALSA MIDI device: %d:%d", client, port);

              if ((result = snd_seq_connect_to(midi->sequencer, midi->port, client, port)) >= 0) {
                if ((result = snd_seq_start_queue(midi->sequencer, midi->queue, NULL)) >= 0) {
                  stopMidiTimer(midi);
                  return midi;
                } else {
                  logMessage(errorLevel, "Cannot start ALSA MIDI queue: %d:%d: %s",
                             client, port, snd_strerror(result));
                }
              } else {
                logMessage(errorLevel, "Cannot connect to ALSA MIDI device: %d:%d: %s",
                           client, port, snd_strerror(result));
              }
            }

            snd_seq_queue_status_free(midi->status);
          } else {
            logMessage(errorLevel, "Cannot allocate ALSA MIDI queue status container: %s",
                       snd_strerror(result));
          }
        } else {
          logMessage(errorLevel, "Cannot allocate ALSA MIDI queue: %s",
                     snd_strerror(result));
        }
      } else {
        logMessage(errorLevel, "Cannot create ALSA MIDI output port: %s",
                   snd_strerror(midi->port));
      }

      snd_seq_close(midi->sequencer);
    } else {
      logMessage(errorLevel, "Cannot open ALSA sequencer: %s: %s",
                 sequencerName, snd_strerror(result));
    }

    free(midi);
  } else {
    logSystemError("MIDI device allocation");
  }
  return NULL;
}

void
closeMidiDevice (MidiDevice *midi) {
  snd_seq_queue_status_free(midi->status);
  snd_seq_close(midi->sequencer);
  free(midi);
}

int
flushMidiDevice (MidiDevice *midi) {
  while (1) {
    int duration;

    updateMidiStatus(midi);
    {
      const snd_seq_real_time_t *time = snd_seq_queue_status_get_real_time(midi->status);
      int seconds = midi->time.tv_sec - time->tv_sec;
      int nanoseconds = midi->time.tv_nsec - time->tv_nsec;
      duration = (seconds * 1000) + (nanoseconds / 1000000);
    }

    if (duration <= 0) break;
    approximateDelay(duration);
  }

  stopMidiTimer(midi);
  return 1;
}

static void
prepareMidiEvent (MidiDevice *midi, snd_seq_event_t *event) {
  snd_seq_ev_clear(event);
  snd_seq_ev_set_source(event, midi->port);
  snd_seq_ev_set_subs(event);
}

static void
scheduleMidiEvent (MidiDevice *midi, snd_seq_event_t *event) {
  snd_seq_ev_schedule_real(event, midi->queue, 1, &midi->time);
}

static int
sendMidiEvent (MidiDevice *midi, snd_seq_event_t *event) {
  int result;

  if ((result = snd_seq_event_output(midi->sequencer, event)) >= 0) {
    snd_seq_drain_output(midi->sequencer);
    return 1;
  } else {
    logMessage(LOG_ERR, "ALSA MIDI write error: %s", snd_strerror(result));
  }
  return 0;
}

int
setMidiInstrument (MidiDevice *midi, unsigned char channel, unsigned char instrument) {
  snd_seq_event_t event;

  prepareMidiEvent(midi, &event);
  snd_seq_ev_set_pgmchange(&event, channel, instrument);
  return sendMidiEvent(midi, &event);
}

int
beginMidiBlock (MidiDevice *midi) {
  startMidiTimer(midi);
  return 1;
}

int
endMidiBlock (MidiDevice *midi) {
  return 1;
}

int
startMidiNote (MidiDevice *midi, unsigned char channel, unsigned char note, unsigned char volume) {
  snd_seq_event_t event;

  prepareMidiEvent(midi, &event);
  snd_seq_ev_set_noteon(&event, channel, note, volume);
  midi->note = note;
  scheduleMidiEvent(midi, &event);
  return sendMidiEvent(midi, &event);
}

int
stopMidiNote (MidiDevice *midi, unsigned char channel) {
  snd_seq_event_t event;

  prepareMidiEvent(midi, &event);
  snd_seq_ev_set_noteoff(&event, channel, midi->note, 0);
  midi->note = 0;
  scheduleMidiEvent(midi, &event);
  return sendMidiEvent(midi, &event);
}

int
insertMidiWait (MidiDevice *midi, int duration) {
  midi->time.tv_sec += duration / 1000;
  midi->time.tv_nsec += (duration % 1000) * 1000000;

  while (midi->time.tv_nsec >= 1000000000) {
    midi->time.tv_nsec -= 1000000000;
    midi->time.tv_sec++;
  }

  return 1;
}
