/*
 * 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>

#define __force
#define __bitwise
#define __user
#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;
}

