/*
 * 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 <stdio.h>
#include <signal.h>
#include <pthread.h>
#include <unistd.h>

#include "libaudiodev.h"

static unsigned int buffer_count;

static struct mutexed_buffer_s {
  unsigned char *data;
  pthread_mutex_t mutex;
  pthread_cond_t has_data;
} *buffers;

/* Termination variable. */
static int terminate;
/* Buffer currently being captured to. */
static unsigned int buf_cap;

static void *play_loop(void *arg) {
  audio_device_t * device = (audio_device_t *)arg;
  unsigned int buf_play = 0;
  while (!terminate) {
    pthread_mutex_lock(&buffers[buf_play].mutex);
    while (buf_cap == buf_play) {
      pthread_cond_wait(&buffers[buf_play].has_data, &buffers[buf_play].mutex);
    }
    pcm_io(device, buffers[buf_play].data, chunk_size);
    pthread_mutex_unlock(&buffers[buf_play].mutex);
    buf_play = (buf_play + 1) % buffer_count;
  }
  return NULL;
}

static void *cap_loop(void *arg) {
  audio_device_t *device = (audio_device_t *)arg;
  int last;
  while (!terminate) {
    pthread_mutex_lock(&buffers[buf_cap].mutex);
    pcm_io(device, buffers[buf_cap].data, chunk_size);
    last = buf_cap;
    buf_cap = (buf_cap + 1) % buffer_count;
    pthread_cond_signal(&buffers[last].has_data);
    pthread_mutex_unlock(&buffers[last].mutex);
  }
  return NULL;
}

static void signal_handler(int signal) {
  printf("Signal Caught.\n");

  terminate = 1;
}

static void dump_line(FILE *fp) {
  int ch;
  while ((ch = fgetc(fp)) != EOF && ch != '\n') {}
}

static void get_choice(char *direction_name, audio_device_list_t *list,
    int *choice) {
  int i;
  while (1) {
    printf("%s devices:\n", direction_name);
    if (list->count == 0) {
      printf("No devices :(\n");
      exit(EXIT_FAILURE);
    }

    for (i = 0; i < list->count; i++) {
      printf("(%d)\nCard %d: %s, %s\n  Device %d: %s [%s], %s", i + 1,
          list->devs[i].card, list->devs[i].dev_id,
          list->devs[i].dev_name, list->devs[i].dev_no,
          list->devs[i].pcm_id, list->devs[i].pcm_name,
          list->devs[i].hwdevname);
      printf("\n");
    }
    printf("\nChoose one(1 - %d): ",  list->count);

    if (scanf("%d", choice) == 0) {
      dump_line(stdin);
      printf("\nThat was an invalid choice.\n");
    } else if (*choice > 0 && *choice <= list->count) {
      break;
    } else {
      printf("\nThat was an invalid choice.\n");
    }
  }
}

static void init_mutexed_buffers(int size) {
  int i;
  buffers = (struct mutexed_buffer_s *)malloc(buffer_count
      * sizeof(struct mutexed_buffer_s));
  if (!buffers) {
    fprintf(stderr, "Error: Could not create audio buffer array.\n");
    exit(EXIT_FAILURE);
  }
  for (i = 0; i < buffer_count; i++) {
    pthread_mutex_init(&buffers[i].mutex, NULL);
    pthread_cond_init(&buffers[i].has_data, NULL);
    buffers[i].data = (unsigned char *)malloc(size * sizeof(char));
    if (!buffers[i].data) {
      fprintf(stderr, "Error: Could not create audio buffers.\n");
      exit(EXIT_FAILURE);
    }
  }
}

void test(int buffer_size, unsigned int ct, int pdev, int cdev) {
  pthread_t capture_thread;
  pthread_t playback_thread;
  buffer_count = ct;
  audio_device_list_t* playback_list = get_device_list(SND_PCM_STREAM_PLAYBACK);
  audio_device_list_t* capture_list = get_device_list(SND_PCM_STREAM_CAPTURE);

  if (pdev == -1) {
    get_choice("playback", playback_list, &pdev);
  } else if (pdev == 0 || pdev > playback_list->count) {
    fprintf(stderr, "Invalid choice for playback device: %d\n", pdev);
    return;
  }
  if (cdev == -1) {
    get_choice("capture", capture_list, &cdev);
  } else if (cdev == 0 || cdev > capture_list->count) {
    fprintf(stderr, "Invalid ch oice for capture device: %d\n", cdev);
    return;
  }

  init_mutexed_buffers(buffer_size);
  terminate = 0;

  signal(SIGINT, signal_handler);
  signal(SIGTERM, signal_handler);
  signal(SIGABRT, signal_handler);

  if (create_sound_handle(&(playback_list->devs[pdev - 1]), buffer_size) ||
      create_sound_handle(&(capture_list->devs[cdev - 1]), buffer_size))
    exit(EXIT_FAILURE);

  buf_cap = 0;

  pthread_create(&playback_thread, NULL, play_loop,
      &(playback_list->devs[pdev - 1]));
  pthread_create(&capture_thread, NULL, cap_loop,
      &(capture_list->devs[cdev - 1]));

  pthread_join(capture_thread, NULL);
  pthread_join(playback_thread, NULL);

  close_sound_handle(&(playback_list->devs[pdev - 1]));
  close_sound_handle(&(capture_list->devs[cdev - 1]));

  free_device_list(playback_list);
  free_device_list(capture_list);

  printf("Exiting.\n");

}

int main(int argc, char **argv) {
  int play_dev = -1;
  int cap_dev = -1;
  int count = 12;
  int size = 512;
  int arg;

  while ((arg = getopt(argc, argv, "i:o:c:s:")) != -1) {
    switch(arg) {
      case 'i':
        cap_dev = atoi(optarg);
        break;
      case 'o':
        play_dev = atoi(optarg);
        break;
      case 'c':
        count = atoi(optarg);
        break;
      case 's':
        size = atoi(optarg);
        break;
      case '?':
        if (optopt == 'i' || optopt == 'o' || optopt == 'c' || optopt == 's') {
          fprintf(stderr, "Option -%c requires an argument.\n", optopt);
        } else {
          fprintf(stderr, "Unknown Option -%c.\n", optopt);
        }
      default:
        return 1;
    }
  }

  test(size, count, play_dev, cap_dev);
  return 0;
}
