/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "audio_hw_generic_caremu"
// #define LOG_NDEBUG 0

#include <errno.h>
#include <stdlib.h>
#include <string.h>

#include <log/log.h>

#include "audio_vbuffer.h"

#define MIN(a, b) (((a) < (b)) ? (a) : (b))

int audio_vbuffer_init(audio_vbuffer_t *audio_vbuffer, size_t frame_count,
                       size_t frame_size) {
  if (!audio_vbuffer) {
    return -EINVAL;
  }
  audio_vbuffer->frame_size = frame_size;
  audio_vbuffer->frame_count = frame_count;
  size_t bytes = frame_count * frame_size;
  audio_vbuffer->data = calloc(bytes, 1);
  if (!audio_vbuffer->data) {
    return -ENOMEM;
  }
  audio_vbuffer->head = 0;
  audio_vbuffer->tail = 0;
  audio_vbuffer->live = 0;
  pthread_mutex_init(&audio_vbuffer->lock, (const pthread_mutexattr_t *)NULL);
  return 0;
}

int audio_vbuffer_destroy(audio_vbuffer_t *audio_vbuffer) {
  if (!audio_vbuffer) {
    return -EINVAL;
  }
  free(audio_vbuffer->data);
  pthread_mutex_destroy(&audio_vbuffer->lock);
  return 0;
}

int audio_vbuffer_live(audio_vbuffer_t *audio_vbuffer) {
  if (!audio_vbuffer) {
    return -EINVAL;
  }
  pthread_mutex_lock(&audio_vbuffer->lock);
  int live = audio_vbuffer->live;
  pthread_mutex_unlock(&audio_vbuffer->lock);
  return live;
}

int audio_vbuffer_dead(audio_vbuffer_t *audio_vbuffer) {
  if (!audio_vbuffer) {
    return -EINVAL;
  }
  pthread_mutex_lock(&audio_vbuffer->lock);
  int dead = audio_vbuffer->frame_count - audio_vbuffer->live;
  pthread_mutex_unlock(&audio_vbuffer->lock);
  return dead;
}

size_t audio_vbuffer_write(audio_vbuffer_t *audio_vbuffer, const void *buffer,
                           size_t frame_count) {
  size_t frames_written = 0;
  pthread_mutex_lock(&audio_vbuffer->lock);

  while (frame_count != 0) {
    int frames = 0;
    if (audio_vbuffer->live == 0 || audio_vbuffer->head > audio_vbuffer->tail) {
      frames =
          MIN(frame_count, audio_vbuffer->frame_count - audio_vbuffer->head);
    } else if (audio_vbuffer->head < audio_vbuffer->tail) {
      frames = MIN(frame_count, audio_vbuffer->tail - (audio_vbuffer->head));
    } else {
      ALOGD("%s audio_vbuffer is full", __func__);
      break;
    }
    memcpy(
        &audio_vbuffer->data[audio_vbuffer->head * audio_vbuffer->frame_size],
        &((uint8_t *)buffer)[frames_written * audio_vbuffer->frame_size],
        frames * audio_vbuffer->frame_size);
    audio_vbuffer->live += frames;
    frames_written += frames;
    frame_count -= frames;
    audio_vbuffer->head =
        (audio_vbuffer->head + frames) % audio_vbuffer->frame_count;
  }

  pthread_mutex_unlock(&audio_vbuffer->lock);
  return frames_written;
}

size_t audio_vbuffer_read(audio_vbuffer_t *audio_vbuffer, void *buffer,
                          size_t frame_count) {
  size_t frames_read = 0;
  pthread_mutex_lock(&audio_vbuffer->lock);

  while (frame_count != 0) {
    int frames = 0;
    if (audio_vbuffer->live == audio_vbuffer->frame_count ||
        audio_vbuffer->tail > audio_vbuffer->head) {
      frames =
          MIN(frame_count, audio_vbuffer->frame_count - audio_vbuffer->tail);
    } else if (audio_vbuffer->tail < audio_vbuffer->head) {
      frames = MIN(frame_count, audio_vbuffer->head - audio_vbuffer->tail);
    } else {
      break;
    }
    memcpy(
        &((uint8_t *)buffer)[frames_read * audio_vbuffer->frame_size],
        &audio_vbuffer->data[audio_vbuffer->tail * audio_vbuffer->frame_size],
        frames * audio_vbuffer->frame_size);
    audio_vbuffer->live -= frames;
    frames_read += frames;
    frame_count -= frames;
    audio_vbuffer->tail =
        (audio_vbuffer->tail + frames) % audio_vbuffer->frame_count;
  }

  pthread_mutex_unlock(&audio_vbuffer->lock);
  return frames_read;
}
