/*
 * Copyright (C) 2017 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.
 */

// Play silence and recover from dead servers or disconnected devices.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include <aaudio/AAudio.h>
#include <aaudio/AAudioTesting.h>
#include "utils/AAudioExampleUtils.h"
#include "../examples/utils/AAudioExampleUtils.h"

// Arbitrary period for glitches, once per second at 48000 Hz.
#define FORCED_UNDERRUN_PERIOD_FRAMES    48000
// How long to sleep in a callback to cause an intentional glitch. For testing.
#define FORCED_UNDERRUN_SLEEP_MICROS     (10 * 1000)

#define MAX_TIMESTAMPS          1000

#define DEFAULT_TIMEOUT_NANOS   ((int64_t)1000000000)

#define NUM_SECONDS             1
#define NUM_LOOPS               4

typedef struct TimestampInfo {
    int64_t         framesTotal;
    int64_t         appPosition; // frames
    int64_t         appNanoseconds;
    int64_t         timestampPosition;  // frames
    int64_t         timestampNanos;
    aaudio_result_t result;
} TimestampInfo;

typedef struct TimestampCallbackData_s {
    TimestampInfo  timestamps[MAX_TIMESTAMPS];
    int64_t        framesTotal = 0;
    int64_t        nextFrameToGlitch = FORCED_UNDERRUN_PERIOD_FRAMES;
    int32_t        timestampCount = 0; // in timestamps
    bool           forceUnderruns = false;
} TimestampCallbackData_t;

// Callback function that fills the audio output buffer.
aaudio_data_callback_result_t timestampDataCallbackProc(
        AAudioStream *stream,
        void *userData,
        void *audioData __unused,
        int32_t numFrames
) {

    // should not happen but just in case...
    if (userData == nullptr) {
        printf("ERROR - SimplePlayerDataCallbackProc needs userData\n");
        return AAUDIO_CALLBACK_RESULT_STOP;
    }
    TimestampCallbackData_t *timestampData = (TimestampCallbackData_t *) userData;

    aaudio_direction_t direction = AAudioStream_getDirection(stream);
    if (direction == AAUDIO_DIRECTION_INPUT) {
        timestampData->framesTotal += numFrames;
    }

    if (timestampData->forceUnderruns) {
        if (timestampData->framesTotal > timestampData->nextFrameToGlitch) {
            usleep(FORCED_UNDERRUN_SLEEP_MICROS);
            printf("Simulate glitch at %lld\n", (long long) timestampData->framesTotal);
            timestampData->nextFrameToGlitch += FORCED_UNDERRUN_PERIOD_FRAMES;
        }
    }

    if (timestampData->timestampCount < MAX_TIMESTAMPS) {
        TimestampInfo *timestamp = &timestampData->timestamps[timestampData->timestampCount];
        timestamp->result = AAudioStream_getTimestamp(stream,
                                                      CLOCK_MONOTONIC,
                                                      &timestamp->timestampPosition,
                                                      &timestamp->timestampNanos);
        timestamp->framesTotal = timestampData->framesTotal;
        timestamp->appPosition = (direction == AAUDIO_DIRECTION_OUTPUT)
                ? AAudioStream_getFramesWritten(stream)
                : AAudioStream_getFramesRead(stream);
        timestamp->appNanoseconds = getNanoseconds();
        timestampData->timestampCount++;
    }

    if (direction == AAUDIO_DIRECTION_OUTPUT) {
        timestampData->framesTotal += numFrames;
    }
    return AAUDIO_CALLBACK_RESULT_CONTINUE;
}

static TimestampCallbackData_t sTimestampData;

static aaudio_result_t testTimeStamps(aaudio_policy_t mmapPolicy,
                           aaudio_sharing_mode_t sharingMode,
                           aaudio_performance_mode_t performanceMode,
                           aaudio_direction_t direction) {
    aaudio_result_t result = AAUDIO_OK;

    int32_t framesPerBurst = 0;
    int32_t actualChannelCount = 0;
    int32_t actualSampleRate = 0;
    int32_t originalBufferSize = 0;
    int32_t requestedBufferSize = 0;
    int32_t finalBufferSize = 0;
    aaudio_format_t actualDataFormat = AAUDIO_FORMAT_PCM_FLOAT;
    aaudio_sharing_mode_t actualSharingMode = AAUDIO_SHARING_MODE_SHARED;
    aaudio_sharing_mode_t actualPerformanceMode = AAUDIO_PERFORMANCE_MODE_NONE;

    AAudioStreamBuilder *aaudioBuilder = nullptr;
    AAudioStream *aaudioStream = nullptr;

    memset(&sTimestampData, 0, sizeof(sTimestampData));

    printf("------------ testTimeStamps(policy = %d, sharing = %s, perf = %s, dir = %s) -----------\n",
           mmapPolicy,
           getSharingModeText(sharingMode),
           getPerformanceModeText(performanceMode),
           getDirectionText(direction));

    AAudio_setMMapPolicy(mmapPolicy);

    // Use an AAudioStreamBuilder to contain requested parameters.
    result = AAudio_createStreamBuilder(&aaudioBuilder);
    if (result != AAUDIO_OK) {
        printf("AAudio_createStreamBuilder returned %s",
               AAudio_convertResultToText(result));
        goto finish;
    }

    // Request stream properties.
    AAudioStreamBuilder_setFormat(aaudioBuilder, AAUDIO_FORMAT_PCM_I16);
    AAudioStreamBuilder_setSharingMode(aaudioBuilder, sharingMode);
    AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, performanceMode);
    AAudioStreamBuilder_setDirection(aaudioBuilder, direction);
    AAudioStreamBuilder_setDataCallback(aaudioBuilder, timestampDataCallbackProc, &sTimestampData);

    // Create an AAudioStream using the Builder.
    result = AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream);
    if (result != AAUDIO_OK) {
        printf("AAudioStreamBuilder_openStream returned %s",
               AAudio_convertResultToText(result));
        goto finish;
    }

    // Check to see what kind of stream we actually got.
    actualSampleRate = AAudioStream_getSampleRate(aaudioStream);
    actualChannelCount = AAudioStream_getChannelCount(aaudioStream);
    actualDataFormat = AAudioStream_getFormat(aaudioStream);

    actualSharingMode = AAudioStream_getSharingMode(aaudioStream);
    if (actualSharingMode != sharingMode) {
        printf("did not get expected sharingMode, got %3d, skipping test\n",
               actualSharingMode);
        result = AAUDIO_OK;
        goto finish;
    }
    actualPerformanceMode = AAudioStream_getPerformanceMode(aaudioStream);
    if (actualPerformanceMode != performanceMode) {
        printf("did not get expected performanceMode, got %3d, skipping test\n",
               actualPerformanceMode);
        result = AAUDIO_OK;
        goto finish;
    }

    printf("    chans = %3d, rate = %6d format = %d\n",
           actualChannelCount, actualSampleRate, actualDataFormat);
    printf("    Is MMAP used? %s\n", AAudioStream_isMMapUsed(aaudioStream)
                                     ? "yes" : "no");

    // This is the number of frames that are read in one chunk by a DMA controller
    // or a DSP or a mixer.
    framesPerBurst = AAudioStream_getFramesPerBurst(aaudioStream);
    printf("    framesPerBurst = %3d\n", framesPerBurst);

    originalBufferSize = AAudioStream_getBufferSizeInFrames(aaudioStream);
    requestedBufferSize = 4 * framesPerBurst;
    finalBufferSize = AAudioStream_setBufferSizeInFrames(aaudioStream, requestedBufferSize);

    printf("    BufferSize: original = %4d, requested = %4d, final = %4d\n",
           originalBufferSize, requestedBufferSize, finalBufferSize);

    {
        int64_t position;
        int64_t nanoseconds;
        result = AAudioStream_getTimestamp(aaudioStream, CLOCK_MONOTONIC, &position, &nanoseconds);
        printf("before start, AAudioStream_getTimestamp() returns %s\n",
               AAudio_convertResultToText(result));
    }

    for (int runs = 0; runs < NUM_LOOPS; runs++) {
        printf("------------------ loop #%d\n", runs);

        int64_t temp = sTimestampData.framesTotal;
        memset(&sTimestampData, 0, sizeof(sTimestampData));
        sTimestampData.framesTotal = temp;

        sTimestampData.forceUnderruns = false;

        result = AAudioStream_requestStart(aaudioStream);
        if (result != AAUDIO_OK) {
            printf("AAudioStream_requestStart returned %s",
                   AAudio_convertResultToText(result));
            goto finish;
        }

        for (int second = 0; second < NUM_SECONDS; second++) {
            // Give AAudio callback time to run in the background.
            sleep(1);

            // Periodically print the progress so we know it hasn't died.
            printf("framesWritten = %d, XRuns = %d\n",
                   (int) AAudioStream_getFramesWritten(aaudioStream),
                   (int) AAudioStream_getXRunCount(aaudioStream)
            );
        }

        result = AAudioStream_requestStop(aaudioStream);
        if (result != AAUDIO_OK) {
            printf("AAudioStream_requestStop returned %s\n",
                   AAudio_convertResultToText(result));
        }

        printf("timestampCount = %d\n", sTimestampData.timestampCount);
        int printed = 0;
        for (int i = 0; i < sTimestampData.timestampCount; i++) {
            TimestampInfo *timestamp = &sTimestampData.timestamps[i];
            bool posChanged = (timestamp->timestampPosition != (timestamp - 1)->timestampPosition);
            bool timeChanged = (timestamp->timestampNanos != (timestamp - 1)->timestampNanos);
            if ((printed < 20) && ((i < 10) || posChanged || timeChanged)) {
                printf("  %3d : frames %8lld, xferd %8lld", i,
                       (long long) timestamp->framesTotal,
                       (long long) timestamp->appPosition);
                if (timestamp->result != AAUDIO_OK) {
                    printf(", result = %s\n", AAudio_convertResultToText(timestamp->result));
                } else {
                    bool negative = timestamp->timestampPosition < 0;
                    bool retro = (i > 0 && (timestamp->timestampPosition <
                                            (timestamp - 1)->timestampPosition));
                    const char *message = negative ? " <=NEGATIVE!"
                                                   : (retro ? "  <= RETROGRADE!" : "");

                    double latency = calculateLatencyMillis(timestamp->timestampPosition,
                                             timestamp->timestampNanos,
                                             timestamp->appPosition,
                                             timestamp->appNanoseconds,
                                             actualSampleRate);
                    printf(", STAMP: pos = %8lld, nanos = %8lld, lat = %7.1f msec %s\n",
                           (long long) timestamp->timestampPosition,
                           (long long) timestamp->timestampNanos,
                           latency,
                           message);
                }
                printed++;
            }
        }

        // Avoid race conditions in AudioFlinger.
        // There is normally a delay between a real user stopping and restarting a stream.
        sleep(1);
    }

finish:
    if (aaudioStream != nullptr) {
        AAudioStream_close(aaudioStream);
    }
    AAudioStreamBuilder_delete(aaudioBuilder);
    printf("result = %d = %s\n", result, AAudio_convertResultToText(result));

    return result;
}

int main(int argc, char **argv) {
    (void) argc;
    (void) argv;

    aaudio_result_t result = AAUDIO_OK;

    // Make printf print immediately so that debug info is not stuck
    // in a buffer if we hang or crash.
    setvbuf(stdout, nullptr, _IONBF, (size_t) 0);

    printf("Test Timestamps V0.1.3\n");

    // Legacy
    aaudio_policy_t policy = AAUDIO_POLICY_NEVER;
    result = testTimeStamps(policy,
                            AAUDIO_SHARING_MODE_SHARED,
                            AAUDIO_PERFORMANCE_MODE_NONE,
                            AAUDIO_DIRECTION_INPUT);
    result = testTimeStamps(policy,
                            AAUDIO_SHARING_MODE_SHARED,
                            AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
                            AAUDIO_DIRECTION_INPUT);
    result = testTimeStamps(policy,
                            AAUDIO_SHARING_MODE_SHARED,
                            AAUDIO_PERFORMANCE_MODE_NONE,
                            AAUDIO_DIRECTION_OUTPUT);
    result = testTimeStamps(policy,
                            AAUDIO_SHARING_MODE_SHARED,
                            AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
                            AAUDIO_DIRECTION_OUTPUT);

    // MMAP
    policy = AAUDIO_POLICY_ALWAYS;
    result = testTimeStamps(policy,
                            AAUDIO_SHARING_MODE_EXCLUSIVE,
                            AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
                            AAUDIO_DIRECTION_INPUT);
    result = testTimeStamps(policy,
                            AAUDIO_SHARING_MODE_EXCLUSIVE,
                            AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
                            AAUDIO_DIRECTION_OUTPUT);
    result = testTimeStamps(policy,
                            AAUDIO_SHARING_MODE_SHARED,
                            AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
                            AAUDIO_DIRECTION_INPUT);
    result = testTimeStamps(policy,
                            AAUDIO_SHARING_MODE_SHARED,
                            AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
                            AAUDIO_DIRECTION_OUTPUT);

    return (result == AAUDIO_OK) ? EXIT_SUCCESS : EXIT_FAILURE;
}
