/*
 * Copyright (c) 2011 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 <alsa/asoundlib.h>
#include <stdlib.h>
#include <stdio.h>

#include "libaudiodev.h"

#define CHANNELS 2
#define SAMPLE_RATE 44100
#define FORMAT SND_PCM_FORMAT_S16
#define NON_BLOCKING 0
#define INTERLEAVED SND_PCM_ACCESS_RW_INTERLEAVED

static size_t bits_per_sample;
static size_t bits_per_frame;
unsigned int chunk_size;

void free_device_list(audio_device_list_t *list) {
  int i;

  for (i=0; i < list->count; i++) {
    free((void *)list->devs[i].dev_id);
    free((void *)list->devs[i].dev_name);
    free((void *)list->devs[i].pcm_id);
    free((void *)list->devs[i].pcm_name);
  }

  free(list->devs);
  free(list);
}

int get_device_count(snd_pcm_stream_t direction) {
  int count = 0;
  int cid = -1;
  int ret;
  int dev;
  char hwname[MAX_HWNAME_SIZE];
  snd_ctl_t *handle;
  snd_ctl_card_info_t *info;

  snd_ctl_card_info_malloc(&info);

  ret = snd_card_next(&cid);
  if (ret == 0 && cid == -1) {
    printf("No %s audio devices found.\n", snd_pcm_stream_name(direction));
  }

  for (; cid != -1 && ret >= 0; ret = snd_card_next(&cid)) {
    snprintf(hwname, MAX_HWNAME_SIZE, "hw:%d", cid);

    ret = snd_ctl_open(&handle, hwname, 0);
    if (ret < 0) {
      fprintf(stderr, "Could not open card %d: %s", cid, snd_strerror(ret));
      continue;
    }

    ret = snd_ctl_card_info(handle, info);
    if (ret < 0) {
      fprintf(stderr, "Could not get info for card %d: %s",
              cid, snd_strerror(ret));
      snd_ctl_close(handle);
      continue;
    }

    dev = -1;
    ret = snd_ctl_pcm_next_device(handle, &dev);
    if (ret >= 0 && dev == -1) {
      fprintf(stderr, "Warning: No devices found on card %d\n", cid);
    }
    for (;dev != -1 && ret >= 0; ret = snd_ctl_pcm_next_device(handle, &dev)) {
      count++;
    }
    if (ret == -1) {
      fprintf(stderr, "Error reading next sound device on card %d\n", cid);
    }
    snd_ctl_close(handle);
  }
  if (ret == -1) {
    fprintf(stderr, "Error reading next sound card\n");
  }

  snd_ctl_card_info_free(info);

  return count;
}

/*
 * Refresh the list of playback or capture devices as specified by direction.
 */
audio_device_list_t * get_device_list(snd_pcm_stream_t direction) {
  int i = 0;
  int cid = -1;
  int ret;
  int dev;
  char hwname[MAX_HWNAME_SIZE];
  snd_ctl_t *handle;
  snd_ctl_card_info_t *info;
  snd_pcm_info_t *pcminfo;
  audio_device_list_t *list = (audio_device_list_t *)malloc(
      sizeof(audio_device_list_t));

  list->count = get_device_count(direction);
  list->devs = (audio_device_t *)malloc(list->count * sizeof(audio_device_t));

  snd_ctl_card_info_malloc(&info);
  snd_pcm_info_malloc(&pcminfo);

  ret = snd_card_next(&cid);
  if (ret == 0 && cid == -1)
    printf("No %s audio devices found.\n", snd_pcm_stream_name(direction));

  for (; cid != -1 && ret >= 0 && i < list->count; ret = snd_card_next(&cid)) {
    snprintf(hwname, MAX_HWNAME_SIZE, "hw:%d", cid);

    ret = snd_ctl_open(&handle, hwname, 0);
    if (ret < 0) {
      fprintf(stderr, "Could not open card %d: %s", cid, snd_strerror(ret));
      continue;
    }

    ret = snd_ctl_card_info(handle, info);
    if (ret < 0) {
      fprintf(stderr, "Could not get info for card %d: %s",
              cid, snd_strerror(ret));
      snd_ctl_close(handle);
      continue;
    }

    dev = -1;
    ret = snd_ctl_pcm_next_device(handle, &dev);
    if (ret >= 0 && dev == -1) {
      fprintf(stderr, "Warning: No devices found on card %d\n", cid);
    }
    for (;dev != -1 && ret >= 0; ret = snd_ctl_pcm_next_device(handle, &dev)) {
      snd_pcm_info_set_device(pcminfo, dev);
      snd_pcm_info_set_subdevice(pcminfo, 0);
      snd_pcm_info_set_stream(pcminfo, direction);
      ret = snd_ctl_pcm_info(handle, pcminfo);
      if (ret < 0) {
        fprintf(stderr, "error getting device info [%d, %d]: %s\n",
                cid, dev, snd_strerror(ret));
        continue;
      }

      list->devs[i].card = cid;
      list->devs[i].dev_no = dev;
      list->devs[i].dev_id = strdup(snd_ctl_card_info_get_id(info));
      list->devs[i].dev_name = strdup(snd_ctl_card_info_get_name(info));
      list->devs[i].pcm_id = strdup(snd_pcm_info_get_id(pcminfo));
      list->devs[i].pcm_name = strdup(snd_pcm_info_get_name(pcminfo));
      list->devs[i].direction = direction;
      list->devs[i].handle = NULL;
      snprintf(list->devs[i].hwdevname, MAX_HWNAME_SIZE, "plughw:%d,%d",
          cid, dev);
      i++;
    }
    if (ret == -1) {
      fprintf(stderr, "Error reading next sound device on card %d\n", cid);
    }
    snd_ctl_close(handle);
  }
  if (i != list->count) {
    fprintf(stderr,
            "Error: expect %d sound device(s) but read only %d device(s)\n",
            list->count, i);
    list->count = i;
  }
  if (ret == -1) {
    fprintf(stderr, "Error reading next sound card\n");
  }

  snd_ctl_card_info_free(info);
  snd_pcm_info_free(pcminfo);

  return list;
}

void close_sound_handle(audio_device_t *device) {
  if (!device || !device->handle)
    return;

  snd_pcm_drop(device->handle);
  snd_pcm_close(device->handle);
  device->handle = NULL;
}

/*
 * Helper to create_sound_handle. Used to set hardware parameters like
 * sample rate, channels, interleaving, etc.
 */
static int set_hw_params(audio_device_t *device, int buffer_size,
                         snd_output_t *log) {
  snd_pcm_hw_params_t *hwparams;
  unsigned int rate_set;

  snd_pcm_hw_params_malloc(&hwparams);

  if (snd_pcm_hw_params_any(device->handle, hwparams) < 0) {
    fprintf(stderr, "No config available for PCM device %s\n",
            device->hwdevname);
    return 1;
  }
  if (snd_pcm_hw_params_set_access(device->handle, hwparams, INTERLEAVED) < 0) {
    fprintf(stderr, "Access type not available on PCM device %s\n",
            device->hwdevname);
    return 2;
  }

  if (snd_pcm_hw_params_set_format(device->handle, hwparams, FORMAT) < 0) {
    fprintf(stderr, "Could not set format for device %s\n", device->hwdevname);
    return 3;
  }

  if (snd_pcm_hw_params_set_channels(device->handle, hwparams, CHANNELS) < 0) {
    fprintf(stderr, "Could not set channel count for device %s\n",
            device->hwdevname);
    return 4;
  }

  /* Try to set rate. Check to see if rate is actually what we requested. */
  rate_set = SAMPLE_RATE;
  if (snd_pcm_hw_params_set_rate_near(device->handle,
                                      hwparams, &rate_set, 0) < 0) {
    fprintf(stderr, "Could not set bitrate near %u for PCM device %s\n",
            SAMPLE_RATE, device->hwdevname);
    return 5;
  }

  if (rate_set != SAMPLE_RATE)
    fprintf(stderr, "Warning: Actual rate(%u) != Requested rate(%u)\n",
            rate_set, SAMPLE_RATE);

  snd_pcm_hw_params_set_periods(device->handle, hwparams, 2, 0);
  snd_pcm_hw_params_set_period_size(device->handle,
                                    hwparams,
                                    buffer_size / 2,
                                    0);

  if (snd_pcm_hw_params(device->handle, hwparams) < 0) {
    fprintf(stderr, "Unable to install hw params:\n");
    snd_pcm_hw_params_dump(hwparams, log);
    return 6;
  }

  return 0;
}

/*
 * Helper to create_sound_handle. Set software parameters. There are
 * very few that are not deprecated.
 */
static int set_sw_params(audio_device_t *device, int buffer_size,
                         snd_output_t *log) {
  snd_pcm_sw_params_t *swparams;
  snd_pcm_sw_params_malloc(&swparams);
  snd_pcm_sw_params_current(device->handle, swparams);

  snd_pcm_sw_params_set_avail_min(device->handle, swparams,
                                  buffer_size / 2);
  snd_pcm_sw_params_set_start_threshold(device->handle, swparams,
                                        buffer_size / 8);

  if (snd_pcm_sw_params(device->handle, swparams) < 0) {
    fprintf(stderr, "Unable to install sw params:\n");
    snd_pcm_sw_params_dump(swparams, log);
    return 1;
  }

  return 0;
}

/*
 * Try to open a sound handle and set all required parameters.
 */
int create_sound_handle(audio_device_t *device, int buffer_size) {
  int ret;
  static snd_output_t *log;

  if (!device || device->handle)
    return 1;

  snd_output_stdio_attach(&log, stderr, 0);

  ret = snd_pcm_open(&(device->handle), device->hwdevname,
                     device->direction, NON_BLOCKING);
  if (ret < 0) {
    fprintf(stderr, "Could not open sound device %s: %s\n",
            device->hwdevname, snd_strerror(ret));
    snd_output_close(log);
    return 2;
  }

  /* Try to set non-blocking mode if requested. */
  if (NON_BLOCKING) {
    ret = snd_pcm_nonblock(device->handle, 1);
    if (ret < 0)
      fprintf(stderr, "Could not set %s to non-blocking mode: %s\n",
              device->hwdevname, snd_strerror(ret));
  }

  if (set_hw_params(device, buffer_size, log) ||
      set_sw_params(device, buffer_size, log)) {
    snd_pcm_close(device->handle);
    device->handle = NULL;
    snd_output_close(log);
    return 3;
  }

  bits_per_sample = snd_pcm_format_physical_width(FORMAT);
  bits_per_frame = bits_per_sample * CHANNELS;
  chunk_size = buffer_size * 8 / bits_per_frame;

  snd_output_close(log);

  return 0;
}

ssize_t pcm_io(audio_device_t *device, unsigned char *data, size_t count) {
  ssize_t completed;
  ssize_t result = 0;
  int res;

  if (device->direction == SND_PCM_STREAM_PLAYBACK && count < chunk_size) {
    snd_pcm_format_set_silence(FORMAT, data + (count * bits_per_frame / 8),
                               (chunk_size - count) * CHANNELS);
    count = chunk_size;
  }
  while (count > 0) {
    if (device->direction == SND_PCM_STREAM_PLAYBACK) {
      completed = snd_pcm_writei(device->handle, data, count);
    } else {
      completed = snd_pcm_readi(device->handle, data, count);
    }
    if (completed == -EAGAIN) {
      snd_pcm_wait(device->handle, 1000);
    } else if (completed == -EPIPE) {
      res = snd_pcm_prepare(device->handle);
      if (res < 0) {
        fprintf(stderr, "Prepare error: %s", snd_strerror(res));
        exit(EXIT_FAILURE);
      }
    } else if (completed < 0) {
      fprintf(stderr, "I/O error in %s: %s, %lu\n",
              snd_pcm_stream_name(device->direction), snd_strerror(completed),
          (long unsigned int)completed);
    } else {
      result += completed;
      count -= completed;
      data += completed * bits_per_frame / 8;
    }
  }
  return result;
}
