/*
 * Copyright (C) 2016 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.
 */
/**
 * Simple fake HAL that supports ALSA MMAP/NOIRQ mode.
 */

#include <iostream>
#include <math.h>
#include <limits>
#include <string.h>
#include <unistd.h>

#include <sound/asound.h>

#include "tinyalsa/asoundlib.h"

#include "FakeAudioHal.h"

//using namespace aaudio;

using sample_t = int16_t;
using std::cout;
using std::endl;

#undef SNDRV_PCM_IOCTL_SYNC_PTR
#define SNDRV_PCM_IOCTL_SYNC_PTR 0xc0884123
#define PCM_ERROR_MAX 128

const int SAMPLE_RATE = 48000;       // Hz
const int CHANNEL_COUNT = 2;

struct pcm {
    int fd;
    unsigned int flags;
    int running:1;
    int prepared:1;
    int underruns;
    unsigned int buffer_size;
    unsigned int boundary;
    char error[PCM_ERROR_MAX];
    struct pcm_config config;
    struct snd_pcm_mmap_status *mmap_status;
    struct snd_pcm_mmap_control *mmap_control;
    struct snd_pcm_sync_ptr *sync_ptr;
    void *mmap_buffer;
    unsigned int noirq_frames_per_msec;
    int wait_for_avail_min;
};

static int pcm_sync_ptr(struct pcm *pcm, int flags) {
    if (pcm->sync_ptr) {
        pcm->sync_ptr->flags = flags;
        if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_SYNC_PTR, pcm->sync_ptr) < 0)
            return -1;
    }
    return 0;
}

int pcm_get_hw_ptr(struct pcm* pcm, unsigned int* hw_ptr) {
    if (!hw_ptr || !pcm) return -EINVAL;

    int result = pcm_sync_ptr(pcm, SNDRV_PCM_SYNC_PTR_HWSYNC);
    if (!result) {
        *hw_ptr = pcm->sync_ptr->s.status.hw_ptr;
    }

    return result;
}

typedef struct stream_tracker {
    struct pcm * pcm;
    int          framesPerBurst;
    sample_t   * hwBuffer;
    int32_t      capacityInFrames;
    int32_t      capacityInBytes;
} stream_tracker_t;

#define FRAMES_PER_BURST_QUALCOMM 192
#define FRAMES_PER_BURST_NVIDIA   128

int fake_hal_open(int card_id, int device_id,
                  int frameCapacity,
                  fake_hal_stream_ptr *streamPP) {
    int framesPerBurst = FRAMES_PER_BURST_QUALCOMM; // TODO update as needed
    int periodCountRequested = frameCapacity / framesPerBurst;
    int periodCount = 32;
    unsigned int offset1;
    unsigned int frames1;
    void *area = nullptr;
    int mmapAvail = 0;

    // Try to match requested size with a power of 2.
    while (periodCount < periodCountRequested && periodCount < 1024) {
        periodCount *= 2;
    }
    std::cout << "fake_hal_open() requested frameCapacity = " << frameCapacity << std::endl;
    std::cout << "fake_hal_open() periodCountRequested = " << periodCountRequested << std::endl;
    std::cout << "fake_hal_open() periodCount = " << periodCount << std::endl;

    // Configuration for an ALSA stream.
    pcm_config cfg;
    memset(&cfg, 0, sizeof(cfg));
    cfg.channels = CHANNEL_COUNT;
    cfg.format = PCM_FORMAT_S16_LE;
    cfg.rate = SAMPLE_RATE;
    cfg.period_count = periodCount;
    cfg.period_size = framesPerBurst;
    cfg.start_threshold = 0; // for NOIRQ, should just start, was     framesPerBurst;
    cfg.stop_threshold = INT32_MAX;
    cfg.silence_size = 0;
    cfg.silence_threshold = 0;
    cfg.avail_min = framesPerBurst;

    stream_tracker_t *streamTracker = (stream_tracker_t *) malloc(sizeof(stream_tracker_t));
    if (streamTracker == nullptr) {
        return -1;
    }
    memset(streamTracker, 0, sizeof(stream_tracker_t));

    streamTracker->pcm = pcm_open(card_id, device_id, PCM_OUT | PCM_MMAP | PCM_NOIRQ, &cfg);
    if (streamTracker->pcm == nullptr) {
        cout << "Could not open device." << endl;
        free(streamTracker);
        return -1;
    }

    streamTracker->framesPerBurst = cfg.period_size; // Get from ALSA
    streamTracker->capacityInFrames = pcm_get_buffer_size(streamTracker->pcm);
    streamTracker->capacityInBytes = pcm_frames_to_bytes(streamTracker->pcm, streamTracker->capacityInFrames);
    std::cout << "fake_hal_open() streamTracker->framesPerBurst = " << streamTracker->framesPerBurst << std::endl;
    std::cout << "fake_hal_open() streamTracker->capacityInFrames = " << streamTracker->capacityInFrames << std::endl;

    if (pcm_is_ready(streamTracker->pcm) < 0) {
        cout << "Device is not ready." << endl;
        goto error;
    }

    if (pcm_prepare(streamTracker->pcm) < 0) {
        cout << "Device could not be prepared." << endl;
        cout << "For Marlin, please enter:" << endl;
        cout << "   adb shell" << endl;
        cout << "   tinymix \"QUAT_MI2S_RX Audio Mixer MultiMedia8\" 1" << endl;
        goto error;
    }
    mmapAvail = pcm_mmap_avail(streamTracker->pcm);
    if (mmapAvail <= 0) {
        cout << "fake_hal_open() mmap_avail is <=0" << endl;
        goto error;
    }
    cout << "fake_hal_open() mmap_avail = " << mmapAvail << endl;

    // Where is the memory mapped area?
    if (pcm_mmap_begin(streamTracker->pcm, &area, &offset1, &frames1) < 0)  {
        cout << "fake_hal_open() pcm_mmap_begin failed" << endl;
        goto error;
    }

    // Clear the buffer.
    memset((sample_t*) area, 0, streamTracker->capacityInBytes);
    streamTracker->hwBuffer = (sample_t*) area;
    streamTracker->hwBuffer[0] = 32000; // impulse

    // Prime the buffer so it can start.
    if (pcm_mmap_commit(streamTracker->pcm, 0, framesPerBurst) < 0) {
        cout << "fake_hal_open() pcm_mmap_commit failed" << endl;
        goto error;
    }

    *streamPP = streamTracker;
    return 1;

error:
    fake_hal_close(streamTracker);
    return -1;
}

int fake_hal_get_mmap_info(fake_hal_stream_ptr stream, mmap_buffer_info *info) {
    stream_tracker_t *streamTracker = (stream_tracker_t *) stream;
    info->fd = streamTracker->pcm->fd; // TODO use tinyalsa function
    info->hw_buffer = streamTracker->hwBuffer;
    info->burst_size_in_frames = streamTracker->framesPerBurst;
    info->buffer_capacity_in_frames = streamTracker->capacityInFrames;
    info->buffer_capacity_in_bytes = streamTracker->capacityInBytes;
    info->sample_rate = SAMPLE_RATE;
    info->channel_count = CHANNEL_COUNT;
    return 0;
}

int fake_hal_start(fake_hal_stream_ptr stream) {
    stream_tracker_t *streamTracker = (stream_tracker_t *) stream;
    if (pcm_start(streamTracker->pcm) < 0) {
        cout << "fake_hal_start failed" << endl;
        return -1;
    }
    return 0;
}

int fake_hal_pause(fake_hal_stream_ptr stream) {
    stream_tracker_t *streamTracker = (stream_tracker_t *) stream;
    if (pcm_stop(streamTracker->pcm) < 0) {
        cout << "fake_hal_stop failed" << endl;
        return -1;
    }
    return 0;
}

int fake_hal_get_frame_counter(fake_hal_stream_ptr stream, int *frame_counter) {
    stream_tracker_t *streamTracker = (stream_tracker_t *) stream;
    if (pcm_get_hw_ptr(streamTracker->pcm, (unsigned int *)frame_counter) < 0) {
        cout << "fake_hal_get_frame_counter failed" << endl;
        return -1;
    }
    return 0;
}

int fake_hal_close(fake_hal_stream_ptr stream) {
    stream_tracker_t *streamTracker = (stream_tracker_t *) stream;
    pcm_close(streamTracker->pcm);
    free(streamTracker);
    return 0;
}

