/*
 * Copyright 2016 The ChromiumOS Authors
 * 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 <getopt.h>
#include <math.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <unistd.h>

static unsigned rate = 48000;
static unsigned channels = 2;
static snd_pcm_format_t format = SND_PCM_FORMAT_S16_LE;
static char* play_dev = "hw:0,0";
/* Buffer size will be the maximum supported by hardware. */
static snd_pcm_uframes_t buffer_frames;
static snd_pcm_uframes_t period_size = 240;

/* Fill frames of zeros. */
static void pcm_fill(snd_pcm_t* handle,
                     snd_pcm_uframes_t frames,
                     int16_t value) {
  int16_t* play_buf;
  int err, i;

  play_buf = calloc(frames * channels, sizeof(play_buf[0]));
  for (i = 0; i < frames * channels; i++)
    play_buf[i] = value;

  printf("Write %ld of value %d into device\n", frames, (int)value);

  if ((err = snd_pcm_mmap_writei(handle, play_buf, frames)) != frames) {
    fprintf(stderr, "write to audio interface failed (%s)\n",
            snd_strerror(err));
  }

  free(play_buf);
}

static void pcm_hw_param(snd_pcm_t* handle) {
  int err;
  snd_pcm_hw_params_t* hw_params;

  if ((err = snd_pcm_hw_params_malloc(&hw_params)) < 0) {
    fprintf(stderr, "cannot allocate hardware parameter structure (%s)\n",
            snd_strerror(err));
    exit(1);
  }

  if ((err = snd_pcm_hw_params_any(handle, hw_params)) < 0) {
    fprintf(stderr, "cannot initialize hardware parameter structure (%s)\n",
            snd_strerror(err));
    exit(1);
  }

  if ((err = snd_pcm_hw_params_set_access(
           handle, hw_params, SND_PCM_ACCESS_MMAP_INTERLEAVED)) < 0) {
    fprintf(stderr, "cannot set access type (%s)\n", snd_strerror(err));
    exit(1);
  }

  if ((err = snd_pcm_hw_params_set_format(handle, hw_params, format)) < 0) {
    fprintf(stderr, "cannot set sample format (%s)\n", snd_strerror(err));
    exit(1);
  }

  if ((err = snd_pcm_hw_params_set_rate_near(handle, hw_params, &rate, 0)) <
      0) {
    fprintf(stderr, "cannot set sample rate (%s)\n", snd_strerror(err));
    exit(1);
  }

  if ((err = snd_pcm_hw_params_set_channels(handle, hw_params, 2)) < 0) {
    fprintf(stderr, "cannot set channel count (%s)\n", snd_strerror(err));
    exit(1);
  }

  /* Makes sure buffer frames is even, or snd_pcm_hw_params will
   * return invalid argument error. */
  if ((err = snd_pcm_hw_params_get_buffer_size_max(hw_params, &buffer_frames)) <
      0) {
    fprintf(stderr, "get buffer max (%s)\n", snd_strerror(err));
    exit(1);
  }

  buffer_frames &= ~0x01;
  if ((err = snd_pcm_hw_params_set_buffer_size_max(handle, hw_params,
                                                   &buffer_frames)) < 0) {
    fprintf(stderr, "set_buffer_size_max (%s)\n", snd_strerror(err));
    exit(1);
  }

  printf("buffer size set to %u\n", (unsigned int)buffer_frames);

  if ((err = snd_pcm_hw_params(handle, hw_params)) < 0) {
    fprintf(stderr, "cannot set parameters (%s)\n", snd_strerror(err));
    exit(1);
  }

  snd_pcm_hw_params_free(hw_params);
}

static void pcm_sw_param(snd_pcm_t* handle) {
  int err;
  snd_pcm_sw_params_t* swparams;
  snd_pcm_uframes_t boundary;

  snd_pcm_sw_params_alloca(&swparams);

  err = snd_pcm_sw_params_current(handle, swparams);
  if (err < 0) {
    fprintf(stderr, "sw_params_current: %s\n", snd_strerror(err));
    exit(1);
  }

  err = snd_pcm_sw_params_get_boundary(swparams, &boundary);
  if (err < 0) {
    fprintf(stderr, "get_boundary: %s\n", snd_strerror(err));
    exit(1);
  }
  printf("boundary = %lu\n", boundary);

  err = snd_pcm_sw_params_set_stop_threshold(handle, swparams, boundary);
  if (err < 0) {
    fprintf(stderr, "set_stop_threshold: %s\n", snd_strerror(err));
    exit(1);
  }

  /* Don't auto start. */
  err = snd_pcm_sw_params_set_start_threshold(handle, swparams, boundary);
  if (err < 0) {
    fprintf(stderr, "set_stop_threshold: %s\n", snd_strerror(err));
    exit(1);
  }

  /* Disable period events. */
  err = snd_pcm_sw_params_set_period_event(handle, swparams, 0);
  if (err < 0) {
    fprintf(stderr, "set_period_event: %s\n", snd_strerror(err));
    exit(1);
  }

  err = snd_pcm_sw_params(handle, swparams);
  if (err < 0) {
    fprintf(stderr, "sw_params: %s\n", snd_strerror(err));
    exit(1);
  }
}

static void pcm_init(snd_pcm_t* handle) {
  int err;
  pcm_hw_param(handle);
  pcm_sw_param(handle);

  if ((err = snd_pcm_prepare(handle)) < 0) {
    fprintf(stderr, "cannot prepare audio interface (%s)\n", snd_strerror(err));
    exit(1);
  }

  if ((err = snd_pcm_start(handle)) < 0) {
    fprintf(stderr, "cannot start audio interface (%s)\n", snd_strerror(err));
    exit(1);
  }
}

/* Waits for target_periods periods and logs time stamp and snd_pcm_avail
 * value in each period.
 */
static void wait_for_periods(snd_pcm_t* handle, unsigned int target_periods) {
  unsigned int num_periods = 0;
  unsigned int wake_period_us = period_size * 1E6 / rate;
  struct timespec now;
  snd_pcm_sframes_t avail_frames;
  while (1) {
    clock_gettime(CLOCK_MONOTONIC_RAW, &now);
    printf("time: %ld.%09ld", (long)now.tv_sec, (long)now.tv_nsec);
    avail_frames = snd_pcm_avail(handle);
    printf(" state: %d, avail frames: %ld, hw_level: %ld\n",
           (int)snd_pcm_state(handle), avail_frames,
           buffer_frames - avail_frames);
    /* Breaks here so we can print the last timestamp and frames. */
    if (num_periods == target_periods)
      break;
    num_periods++;
    usleep(wake_period_us);
  }
}

void check_hw_level_in_range(snd_pcm_sframes_t hw_level,
                             snd_pcm_sframes_t min,
                             snd_pcm_sframes_t max) {
  printf("Expected range: %ld - %ld\n", min, max);
  if (hw_level <= max && hw_level >= min) {
    printf("hw_level is in the expected range\n");
  } else {
    fprintf(stderr, "hw_level is not in the expected range\n");
    exit(1);
  }
}

void move_appl_ptr(snd_pcm_t* handle, snd_pcm_sframes_t fuzz) {
  int err = 0;
  snd_pcm_sframes_t to_move, hw_level, avail_frames;

  avail_frames = snd_pcm_avail(handle);
  printf("Available frames: %ld\n", avail_frames);
  hw_level = buffer_frames - avail_frames;
  printf("hw_level frames: %ld\n", hw_level);

  /* We want to move appl_ptr to hw_ptr plus fuzz such that hardware can
   * play the new samples as quick as possible.
   * The difference between hw_ptr and app can be inferred from snd_pcm_avail.
   *    avail = buffer_frames - appl_ptr + hw_ptr
   * => hw_ptr - appl_ptr = avail - buffer_frames.
   * The amount to forward is fuzz - hw_level = fuzz - appl_ptr - hw_ptr.
   * Depending on the sign of this value, we need to forward or rewind
   * appl_ptr. Check go/cros-low-latency for detailed explanation.
   */
  to_move = fuzz + avail_frames - buffer_frames;
  if (to_move > 0) {
    printf("forward by %ld\n", to_move);
    err = snd_pcm_forward(handle, to_move);
  } else if (to_move < 0) {
    printf("rewind by %ld\n", -to_move);
    err = snd_pcm_rewind(handle, -to_move);
  } else {
    printf("no need to move\n");
    return;
  }

  if (err < 0) {
    fprintf(stderr, "cannot move appl ptr (%s)\n", snd_strerror(err));
    exit(1);
  }
}

void check_appl_ptr(snd_pcm_t* handle, snd_pcm_sframes_t fuzz) {
  snd_pcm_sframes_t hw_level, avail_frames;
  int periods_after_move;
  struct timespec time_1, time_2;
  snd_pcm_sframes_t level_1, level_2;
  float time_diff, measure_rate;

  /* Checks the result after moving. The hw_level should be in the range
   * 0 - fuzz. */
  avail_frames = snd_pcm_avail(handle);
  printf("Available frames after move: %ld\n", avail_frames);
  hw_level = buffer_frames - avail_frames;
  printf("hw_level after moving: %ld\n", hw_level);

  check_hw_level_in_range(hw_level, 0, fuzz);

  /* Fills some zeros after moving to make sure PCM still plays fine.
   * Sets periods_after_move so device will play half of buffer size.
   * This would result in an accurate estimated sampling rate. */
  periods_after_move = (buffer_frames >> 1) / period_size;
  printf("Test playback for %d periods after move\n", periods_after_move);
  pcm_fill(handle, period_size * periods_after_move, 0);
  clock_gettime(CLOCK_MONOTONIC_RAW, &time_1);
  printf("time: %ld.%09ld", (long)time_1.tv_sec, (long)time_1.tv_nsec);
  level_1 = buffer_frames - snd_pcm_avail(handle);
  printf(" hw_level after filling %d period is %ld\n", periods_after_move,
         level_1);

  wait_for_periods(handle, periods_after_move - 1);

  clock_gettime(CLOCK_MONOTONIC_RAW, &time_2);
  printf("time: %ld.%09ld", (long)time_2.tv_sec, (long)time_2.tv_nsec);
  level_2 = buffer_frames - snd_pcm_avail(handle);
  printf(" hw_level after playing %d period is %ld\n", periods_after_move - 1,
         level_2);

  /* Checks the device consumption rate in this duration is reasonable. */
  time_diff = (time_2.tv_sec - time_1.tv_sec) +
              (float)(time_2.tv_nsec - time_1.tv_nsec) * 1E-9;
  measure_rate = (level_1 - level_2) / time_diff;

  if (fabsf(measure_rate - rate) <= 1000) {
    printf("rate %f is in the expected range near %u\n", measure_rate, rate);
  } else {
    fprintf(stderr, "rate %f is not in the expected range near %u\n",
            measure_rate, rate);
    exit(1);
  }
}

void move_and_check(snd_pcm_t* handle, snd_pcm_sframes_t fuzz) {
  move_appl_ptr(handle, fuzz);
  check_appl_ptr(handle, fuzz);
}

void alsa_move_test(unsigned int wait_periods) {
  int err;
  snd_pcm_t* handle;
  snd_pcm_sframes_t fuzz = 50;

  if ((err = snd_pcm_open(&handle, play_dev, SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
    fprintf(stderr, "cannot open audio device %s (%s)\n", play_dev,
            snd_strerror(err));
    exit(1);
  }

  pcm_init(handle);

  pcm_fill(handle, buffer_frames, 0);

  wait_for_periods(handle, wait_periods);

  move_and_check(handle, fuzz);

  if ((err = snd_pcm_close(handle)) < 0) {
    fprintf(stderr, "cannot close device (%s)\n", snd_strerror(err));
    exit(1);
  }
}

/* Checks if snd_pcm_drop resets the hw_ptr to 0. See bug crosbug.com/p/51882.
 */
void alsa_drop_test() {
  int err;
  snd_pcm_t* handle;
  snd_pcm_sframes_t frames;
  snd_pcm_sframes_t fuzz = 50;
  unsigned int wait_periods = 50;

  if ((err = snd_pcm_open(&handle, play_dev, SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
    fprintf(stderr, "cannot open audio device %s (%s)\n", play_dev,
            snd_strerror(err));
    exit(1);
  }

  pcm_init(handle);

  pcm_fill(handle, buffer_frames, 0);

  wait_for_periods(handle, wait_periods);

  /* Drop the samples. */
  if ((err = snd_pcm_drop(handle)) < 0) {
    fprintf(stderr, "cannot drop audio interface (%s)\n", snd_strerror(err));
    exit(1);
  }

  /* Prepare and start playback again. */
  if ((err = snd_pcm_prepare(handle)) < 0) {
    fprintf(stderr, "cannot prepare audio interface (%s)\n", snd_strerror(err));
    exit(1);
  }

  if ((err = snd_pcm_start(handle)) < 0) {
    fprintf(stderr, "cannot start for the second time (%s)\n",
            snd_strerror(err));
    exit(1);
  }

  /* The avail should be a reasonable value that is slightly larger than
   * buffer level. avail = buffer - (appl_ptr - hw_ptr).
   * The expected behavior:
   * snd_pcm_drop: hw_ptr should be 0.
   * snd_pcm_prepare: appl_ptr should be the same as hw_ptr, which is 0.
   * snd_pcm_start: hw_ptr gets synced to hardware, should be a small number.
   * So, the new avail should be slightly larger than buffer. */
  frames = snd_pcm_avail(handle);

  printf("Avail frames after drop, prepare, start: %d\n", (int)frames);

  if ((err = snd_pcm_close(handle)) < 0) {
    fprintf(stderr, "cannot close device (%s)\n", snd_strerror(err));
    exit(1);
  }

  printf("Expected avail frames after drop, prepare, start is 0 - %d\n",
         (int)(buffer_frames + fuzz));

  if (frames < 0 || frames > buffer_frames + fuzz) {
    fprintf(stderr, "Avail frames after drop, prepare, start is %d\n",
            (int)frames);
    exit(1);
  }
}

void alsa_fill_test() {
  int err;
  snd_pcm_t* handle;
  unsigned int wait_periods = 10;
  const snd_pcm_channel_area_t* my_areas;
  snd_pcm_uframes_t offset, frames;
  int16_t *dst, *zeros;
  int n_bytes;

  if ((err = snd_pcm_open(&handle, play_dev, SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
    fprintf(stderr, "cannot open audio device %s (%s)\n", play_dev,
            snd_strerror(err));
    exit(1);
  }

  pcm_init(handle);

  /* Write nonzero values into buffer. */
  pcm_fill(handle, buffer_frames, 1);

  /* Play for some periods. */
  wait_for_periods(handle, wait_periods);

  /* Get the mmap area. */
  err = snd_pcm_mmap_begin(handle, &my_areas, &offset, &frames);
  if (err < 0) {
    fprintf(stderr, "cannot mmap begin (%s)\n", snd_strerror(err));
    exit(1);
  }

  /* Fill whole buffer with zeros without committing it.
   * The number of bytes is buffer_frames * channel * 2 (16 bit sample) */
  n_bytes = buffer_frames * channels * 2;
  memset((int8_t*)my_areas[0].addr, 0, n_bytes);
  printf("Filled mmap buffer with zeros\n");

  /* Play for some periods. */
  wait_for_periods(handle, wait_periods);

  /* Check the samples in buffer are all zeros. */
  err = snd_pcm_mmap_begin(handle, &my_areas, &offset, &frames);
  if (err < 0) {
    fprintf(stderr, "cannot mmap begin the second time (%s)\n",
            snd_strerror(err));
    exit(1);
  }
  dst = (int16_t*)my_areas[0].addr;

  zeros = calloc(buffer_frames * channels, sizeof(zeros[0]));

  if (memcmp(zeros, dst, n_bytes)) {
    fprintf(stderr, "buffer is not all zeros\n");
    free(zeros);
    exit(1);
  }
  free(zeros);
  printf("Buffer is filled with zeros\n");
}

int main(int argc, char* argv[]) {
  int c, drop_test = 0, move_test = 0, fill_test = 0;
  const char* short_opt = "hd:rm";
  struct option long_opt[] = {{"help", no_argument, NULL, 'h'},
                              {"device", required_argument, NULL, 'd'},
                              {"drop", no_argument, NULL, 'r'},
                              {"move", no_argument, NULL, 'm'},
                              {"fill", no_argument, NULL, 'f'},
                              {NULL, 0, NULL, 0}};

  while (1) {
    c = getopt_long(argc, argv, short_opt, long_opt, NULL);
    if (c == -1)
      break;
    switch (c) {
      case 'd':
        play_dev = optarg;
        printf("Assign play_dev to %s\n", play_dev);
        break;

      case 'r':
        drop_test = 1;
        printf("Test snd_pcm_drop\n");
        break;

      case 'm':
        move_test = 1;
        printf("Test snd_pcm_forward\n");
        break;

      case 'f':
        fill_test = 1;
        printf("Test snd_pcm_mmap_begin and filling buffer.\n");
        break;

      case 'h':
        printf("Usage: %s [OPTIONS]\n", argv[0]);
        printf("  --device <Device>       Device, default to hw:0,0\n");
        printf("  -h, --help              Print this help and exit\n");
        printf("  --drop                  Test snd_pcm_drop\n");
        printf(
            "  --move                  Test snd_pcm_rewind and "
            "snd_pcm_forward\n");
        printf("  --fill                  Test snd_pcm_mmap_begin\n");
        printf("\n");
        return (0);
        break;

      case ':':
      case '?':
        fprintf(stderr, "Try `%s --help' for more information.\n", argv[0]);
        exit(EXIT_FAILURE);

      default:
        fprintf(stderr, "%s: invalid option -- %c\n", argv[0], c);
        fprintf(stderr, "Try `%s --help' for more information.\n", argv[0]);
        exit(EXIT_FAILURE);
    }
  }

  if (drop_test) {
    alsa_drop_test();
    exit(0);
  }

  if (move_test) {
    /* Test rewind and forward.
     * - Waiting 10 periods: appl_ptr is still ahead of hw_ptr, test
     *                       snd_pcm_rewind call.
     * - Waiting 1000 periods: hw_ptr is ahead of appl_ptr, test
     *                         snd_pcm_forward call.
     */
    alsa_move_test(10);
    alsa_move_test(1000);
    exit(0);
  }

  if (fill_test) {
    alsa_fill_test();
    exit(0);
  }

  exit(0);
}
