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

#pragma once

/*
 * BUFLOG creates up to BUFLOG_MAXSTREAMS simultaneous streams [0:15] of audio buffer data
 * and saves them to disk. The files are stored in the path specified in BUFLOG_BASE_PATH and
 * are named following this format:
 *   YYYYMMDDHHMMSS_id_format_channels_samplingrate.raw
 *
 * Normally we strip BUFLOG dumps from release builds.
 * You can modify this (for example with "#define BUFLOG_NDEBUG 0"
 * at the top of your source file) to change that behavior.
 *
 * usage:
 * - Add this to the top of the source file you want to debug:
 *   #define BUFLOG_NDEBUG 0
 *   #include "BufLog.h"
 *
 * - dump an audio buffer
 *  BUFLOG(buff_id, buff_tag, format, channels, sampling_rate, max_bytes, buff_pointer, buff_size);
 *
 *  buff_id:   int [0:15]   buffer id. If a buffer doesn't exist, it is created the first time.
 *  buff_tag:  char*        string tag used on stream filename and logs
 *  format:    int          Audio format (audio_format_t see audio.h)
 *  channels:  int          Channel Count
 *  sampling_rate:  int     Sampling rate in Hz. e.g. 8000, 16000, 44100, 48000, etc
 *  max_bytes: int [0 or positive number]
 *                          Maximum size of the file (in bytes) to be output.
 *                          If the value is 0, no limit.
 *  buff_pointer: void *    Pointer to audio buffer.
 *  buff_size:  int         Size (in bytes) of the current audio buffer to be stored.
 *
 *
 *  Example usage:
 *    int format       = mConfig.outputCfg.format;
 *    int channels     = audio_channel_count_from_out_mask(mConfig.outputCfg.channels);
 *    int samplingRate = mConfig.outputCfg.samplingRate;
 *    int frameCount   = mConfig.outputCfg.buffer.frameCount;
 *    int frameSize    = audio_bytes_per_sample((audio_format_t)format) * channels;
 *    int buffSize     = frameCount * frameSize;
 *    long maxBytes = 10 * samplingRate * frameSize; //10 seconds max
 *  BUFLOG(11, "loudnes_enhancer_out", format, channels, samplingRate, maxBytes,
 *                               mConfig.outputCfg.buffer.raw, buffSize);
 *
 *  Other macros:
 *  BUFLOG_EXISTS       returns true if there is an instance of BufLog
 *
 *  BUFLOG_RESET        If an instance of BufLog exists, it stops the capture and closes all
 *                      streams.
 *                      If a new call to BUFLOG(..) is done, new streams are created.
 */

#ifndef BUFLOG_NDEBUG
#ifdef NDEBUG
#define BUFLOG_NDEBUG 1
#else
#define BUFLOG_NDEBUG 0
#endif
#endif

/*
 * Simplified macro to send a buffer.
 */
#ifndef BUFLOG
#define __BUFLOG(STREAMID, TAG, FORMAT, CHANNELS, SAMPLINGRATE, MAXBYTES, BUF, SIZE) \
    BufLogSingleton::instance()->write(STREAMID, TAG, FORMAT, CHANNELS, SAMPLINGRATE, MAXBYTES, \
            BUF, SIZE)
#if BUFLOG_NDEBUG
#define BUFLOG(STREAMID, TAG, FORMAT, CHANNELS, SAMPLINGRATE, MAXBYTES, BUF, SIZE) \
    do { if (0) {  } } while (0)
#else
#define BUFLOG(STREAMID, TAG, FORMAT, CHANNELS, SAMPLINGRATE, MAXBYTES, BUF, SIZE) \
    __BUFLOG(STREAMID, TAG, FORMAT, CHANNELS, SAMPLINGRATE, MAXBYTES, BUF, SIZE)
#endif
#endif

#ifndef BUFLOG_EXISTS
#define BUFLOG_EXISTS BufLogSingleton::instanceExists()
#endif

#ifndef BUFLOG_RESET
#define BUFLOG_RESET do { if (BufLogSingleton::instanceExists()) { \
    BufLogSingleton::instance()->reset(); } } while (0)
#endif

#include <mutex>
#include <stdint.h>
#include <stdio.h>
#include <sys/types.h>

//BufLog configuration
#define BUFLOGSTREAM_MAX_TAGSIZE    32
#define BUFLOG_BASE_PATH            "/data/misc/audioserver"
#define BUFLOG_MAX_PATH_SIZE        300

namespace android {

class BufLogStream {
public:
    BufLogStream(unsigned int id,
            const char *tag,
            unsigned int format,
            unsigned int channels,
            unsigned int samplingRate,
            size_t maxBytes);
    ~BufLogStream();

    // write buffer to stream
    //  buf:  pointer to buffer
    //  size: number of bytes to write
    size_t          write(const void *buf, size_t size);

    // pause/resume stream
    //  pause: true = paused, false = not paused
    //  return value: previous state of stream (paused or not).
    bool            setPause(bool pause);

    // will stop the stream and close any open file
    // the stream can't be reopen. Instead, a new stream (and file) should be created.
    void            finalize();

private:
    const unsigned int  mId;
    const unsigned int  mFormat;
    const unsigned int  mChannels;
    const unsigned int  mSamplingRate;
    const size_t        mMaxBytes;
    char                mTag[BUFLOGSTREAM_MAX_TAGSIZE + 1]; // const, set in ctor.

    mutable std::mutex  mLock;
    bool                mPaused = false;
    size_t              mByteCount = 0;
    FILE                *mFile; // set in ctor

    void            closeStream_l();
};

class BufLog {
public:
    ~BufLog();

    //  streamid:      int [0:BUFLOG_MAXSTREAMS-1]   buffer id.
    //                  If a buffer doesn't exist, it is created the first time is referenced
    //  tag:           char*  string tag used on stream filename and logs
    //  format:        int Audio format (audio_format_t see audio.h)
    //  channels:      int          Channel Count
    //  samplingRate:  int Sampling rate in Hz. e.g. 8000, 16000, 44100, 48000, etc
    //  maxBytes:      int [0 or positive number]
    //                  Maximum size of the file (in bytes) to be output.
    //                  If the value is 0, no limit.
    //  size:          int Size (in bytes) of the current audio buffer to be written.
    //  buf:           void *    Pointer to audio buffer.
    size_t          write(int streamid,
                        const char *tag,
                        int format,
                        int channels,
                        int samplingRate,
                        size_t maxBytes,
                        const void *buf,
                        size_t size);

    // reset will stop and close all active streams, thus finalizing any open file.
    //  New streams will be created if write() is called again.
    void            reset();

protected:
    static constexpr size_t BUFLOG_MAXSTREAMS = 16;
    mutable std::mutex mLock;
    BufLogStream *mStreams[BUFLOG_MAXSTREAMS]{};
};

class BufLogSingleton {
public:
    static BufLog   *instance();
    static bool     instanceExists();

private:
    static void     initOnce();
    static BufLog   *mInstance;
};

} // namespace android
