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

package org.drrickorang.loopback;

import java.nio.ByteBuffer;
import java.util.Arrays;

import android.util.Log;
import android.os.Handler;
import android.os.Message;


/**
 * A thread/audio track based audio synth.
 */

public class NativeAudioThread extends Thread {
    private static final String TAG = "NativeAudioThread";

    // for latency test
    static final int LOOPBACK_NATIVE_AUDIO_THREAD_MESSAGE_LATENCY_REC_STARTED = 891;
    static final int LOOPBACK_NATIVE_AUDIO_THREAD_MESSAGE_LATENCY_REC_ERROR = 892;
    static final int LOOPBACK_NATIVE_AUDIO_THREAD_MESSAGE_LATENCY_REC_COMPLETE = 893;
    static final int LOOPBACK_NATIVE_AUDIO_THREAD_MESSAGE_LATENCY_REC_COMPLETE_ERRORS = 894;
    static final int LOOPBACK_NATIVE_AUDIO_THREAD_MESSAGE_LATENCY_REC_STOP = 895;

    // for buffer test
    static final int LOOPBACK_NATIVE_AUDIO_THREAD_MESSAGE_BUFFER_REC_STARTED = 896;
    static final int LOOPBACK_NATIVE_AUDIO_THREAD_MESSAGE_BUFFER_REC_ERROR = 897;
    static final int LOOPBACK_NATIVE_AUDIO_THREAD_MESSAGE_BUFFER_REC_COMPLETE = 898;
    static final int LOOPBACK_NATIVE_AUDIO_THREAD_MESSAGE_BUFFER_REC_COMPLETE_ERRORS = 899;
    static final int LOOPBACK_NATIVE_AUDIO_THREAD_MESSAGE_BUFFER_REC_STOP = 900;

    public boolean  mIsRunning = false;
    public int      mSessionId;
    public double[] mSamples; // store samples that will be shown on WavePlotView
    int             mSamplesIndex;

    private int mTestType;
    private int mSamplingRate;
    private int mMinPlayerBufferSizeInBytes = 0;
    private int mMinRecorderBuffSizeInBytes = 0; // currently not used
    private int mMicSource;
    private int mPerformanceMode = -1;
    private int mIgnoreFirstFrames;

    private boolean mIsRequestStop = false;
    private Handler mMessageHandler;
    private boolean isDestroying = false;
    private boolean hasDestroyingErrors = false;

    // for buffer test
    private int[]   mRecorderBufferPeriod;
    private int     mRecorderMaxBufferPeriod;
    private double  mRecorderStdDevBufferPeriod;
    private int[]   mPlayerBufferPeriod;
    private int     mPlayerMaxBufferPeriod;
    private double  mPlayerStdDevBufferPeriod;
    private BufferCallbackTimes mPlayerCallbackTimes;
    private BufferCallbackTimes mRecorderCallbackTimes;
    private int     mBufferTestWavePlotDurationInSeconds;
    private double  mFrequency1 = Constant.PRIME_FREQUENCY_1;
    private double  mFrequency2 = Constant.PRIME_FREQUENCY_2; // not actually used
    private int     mBufferTestDurationInSeconds;
    private int     mFFTSamplingSize;
    private int     mFFTOverlapSamples;
    private int[]   mAllGlitches;
    private boolean mGlitchingIntervalTooLong;
    private final CaptureHolder mCaptureHolder;

    private PipeByteBuffer        mPipeByteBuffer;
    private GlitchDetectionThread mGlitchDetectionThread;


    public NativeAudioThread(int samplingRate, int playerBufferInBytes, int recorderBufferInBytes,
                             int micSource, int performanceMode, int testType, int bufferTestDurationInSeconds,
                             int bufferTestWavePlotDurationInSeconds, int ignoreFirstFrames,
                             CaptureHolder captureHolder) {
        mSamplingRate = samplingRate;
        mMinPlayerBufferSizeInBytes = playerBufferInBytes;
        mMinRecorderBuffSizeInBytes = recorderBufferInBytes;
        mMicSource = micSource;
        mPerformanceMode = performanceMode;
        mTestType = testType;
        mBufferTestDurationInSeconds = bufferTestDurationInSeconds;
        mBufferTestWavePlotDurationInSeconds = bufferTestWavePlotDurationInSeconds;
        mIgnoreFirstFrames = ignoreFirstFrames;
        mCaptureHolder = captureHolder;
        setName("Loopback_NativeAudio");
    }

    public NativeAudioThread(NativeAudioThread old) {
        mSamplingRate = old.mSamplingRate;
        mMinPlayerBufferSizeInBytes = old.mMinPlayerBufferSizeInBytes;
        mMinRecorderBuffSizeInBytes = old.mMinRecorderBuffSizeInBytes;
        mMicSource = old.mMicSource;
        mPerformanceMode = old.mPerformanceMode;
        mTestType = old.mTestType;
        mBufferTestDurationInSeconds = old.mBufferTestDurationInSeconds;
        mBufferTestWavePlotDurationInSeconds = old.mBufferTestWavePlotDurationInSeconds;
        mIgnoreFirstFrames = old.mIgnoreFirstFrames;
        mCaptureHolder = old.mCaptureHolder;
        setName("Loopback_NativeAudio");
    }

    //JNI load
    static {
        try {
            System.loadLibrary("loopback");
        } catch (UnsatisfiedLinkError e) {
            log("Error loading loopback JNI library");
            e.printStackTrace();
        }
        /* TODO: gracefully fail/notify if the library can't be loaded */
    }


    //jni calls
    public native long  slesInit(int samplingRate, int frameCount, int micSource,
                                 int performanceMode,
                                 int testType, double frequency1, ByteBuffer byteBuffer,
                                 short[] sincTone, int maxRecordedLateCallbacks,
                                 int ignoreFirstFrames);
    public native int   slesProcessNext(long sles_data, double[] samples, long offset);
    public native int   slesDestroy(long sles_data);

    // to get buffer period data
    public native int[]  slesGetRecorderBufferPeriod(long sles_data);
    public native int    slesGetRecorderMaxBufferPeriod(long sles_data);
    public native double slesGetRecorderVarianceBufferPeriod(long sles_data);
    public native int[]  slesGetPlayerBufferPeriod(long sles_data);
    public native int    slesGetPlayerMaxBufferPeriod(long sles_data);
    public native double slesGetPlayerVarianceBufferPeriod(long sles_data);
    public native BufferCallbackTimes slesGetPlayerCallbackTimeStamps(long sles_data);
    public native BufferCallbackTimes slesGetRecorderCallbackTimeStamps(long sles_data);

    public native int slesGetCaptureRank(long sles_data);


    public void run() {
        setPriority(Thread.MAX_PRIORITY);
        mIsRunning = true;

        //erase output buffer
        if (mSamples != null)
            mSamples = null;

        //start playing
        log(" Started capture test");
        if (mMessageHandler != null) {
            Message msg = Message.obtain();
            switch (mTestType) {
            case Constant.LOOPBACK_PLUG_AUDIO_THREAD_TEST_TYPE_LATENCY:
                msg.what = LOOPBACK_NATIVE_AUDIO_THREAD_MESSAGE_LATENCY_REC_STARTED;
                break;
            case Constant.LOOPBACK_PLUG_AUDIO_THREAD_TEST_TYPE_BUFFER_PERIOD:
                msg.what = LOOPBACK_NATIVE_AUDIO_THREAD_MESSAGE_BUFFER_REC_STARTED;
                break;
            }
            mMessageHandler.sendMessage(msg);
        }

        //generate sinc tone use for loopback test
        short loopbackTone[] = new short[mMinPlayerBufferSizeInBytes / Constant.BYTES_PER_FRAME];
        if (mTestType == Constant.LOOPBACK_PLUG_AUDIO_THREAD_TEST_TYPE_LATENCY) {
            ToneGeneration sincToneGen = new RampedSineTone(mSamplingRate,
                    Constant.LOOPBACK_FREQUENCY);
            sincToneGen.generateTone(loopbackTone, loopbackTone.length);
        }

        log(String.format("about to init, sampling rate: %d, buffer:%d", mSamplingRate,
                mMinPlayerBufferSizeInBytes / Constant.BYTES_PER_FRAME));

        // mPipeByteBuffer is only used in buffer test
        mPipeByteBuffer = new PipeByteBuffer(Constant.MAX_SHORTS);
        long startTimeMs = System.currentTimeMillis();
        long sles_data = slesInit(mSamplingRate,
                mMinPlayerBufferSizeInBytes / Constant.BYTES_PER_FRAME, mMicSource,
                mPerformanceMode, mTestType,
                mFrequency1, mPipeByteBuffer.getByteBuffer(), loopbackTone,
                mBufferTestDurationInSeconds * Constant.MAX_RECORDED_LATE_CALLBACKS_PER_SECOND,
                mIgnoreFirstFrames);
        log(String.format("sles_data = 0x%X", sles_data));

        if (sles_data == 0) {
            //notify error!!
            log(" ERROR at JNI initialization");
            if (mMessageHandler != null) {
                Message msg = Message.obtain();
                switch (mTestType) {
                case Constant.LOOPBACK_PLUG_AUDIO_THREAD_TEST_TYPE_LATENCY:
                    msg.what = LOOPBACK_NATIVE_AUDIO_THREAD_MESSAGE_LATENCY_REC_ERROR;
                    break;
                case Constant.LOOPBACK_PLUG_AUDIO_THREAD_TEST_TYPE_BUFFER_PERIOD:
                    msg.what = LOOPBACK_NATIVE_AUDIO_THREAD_MESSAGE_BUFFER_REC_ERROR;
                    break;
                }
                mMessageHandler.sendMessage(msg);
            }
        } else {
            // wait a little bit
            try {
                final int setUpTime = 10;
                sleep(setUpTime); //just to let it start properly
            } catch (InterruptedException e) {
                e.printStackTrace();
            }


            int totalSamplesRead = 0;
            switch (mTestType) {
            case Constant.LOOPBACK_PLUG_AUDIO_THREAD_TEST_TYPE_LATENCY:
                final int latencyTestDurationInSeconds = 2;
                int nNewSize = (int) (1.1 * mSamplingRate * latencyTestDurationInSeconds);
                mSamples = new double[nNewSize];
                mSamplesIndex = 0; //reset index
                Arrays.fill(mSamples, 0);

                //TODO use a ByteBuffer to retrieve recorded data instead
                long offset = 0;
                // retrieve native recorder's recorded data
                for (int ii = 0; ii < latencyTestDurationInSeconds; ii++) {
                    log(String.format("block %d...", ii));
                    int samplesRead = slesProcessNext(sles_data, mSamples, offset);
                    totalSamplesRead += samplesRead;
                    offset += samplesRead;
                    log(" [" + ii + "] jni samples read:" + samplesRead +
                        "  currentOffset:" + offset);
                }

                log(String.format(" samplesRead: %d, sampleOffset:%d", totalSamplesRead, offset));
                log("about to destroy...");
                break;
            case Constant.LOOPBACK_PLUG_AUDIO_THREAD_TEST_TYPE_BUFFER_PERIOD:
                setUpGlitchDetectionThread();
                long testDurationMs = mBufferTestDurationInSeconds * Constant.MILLIS_PER_SECOND;
                long elapsedTimeMs = System.currentTimeMillis() - startTimeMs;
                while (elapsedTimeMs < testDurationMs) {
                    if (mIsRequestStop) {
                        break;
                    } else {
                        int rank = slesGetCaptureRank(sles_data);
                        if (rank > 0) {
                            //log("Late callback detected");
                            mCaptureHolder.captureState(rank);
                        }
                        try {
                            final int setUpTime = 100;
                            sleep(setUpTime); //just to let it start properly
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        elapsedTimeMs = System.currentTimeMillis() - startTimeMs;
                    }

                }
                break;


            }

            // collect buffer period data
            mRecorderBufferPeriod = slesGetRecorderBufferPeriod(sles_data);
            mRecorderMaxBufferPeriod = slesGetRecorderMaxBufferPeriod(sles_data);
            mRecorderStdDevBufferPeriod = Math.sqrt(slesGetRecorderVarianceBufferPeriod(sles_data));
            mPlayerBufferPeriod = slesGetPlayerBufferPeriod(sles_data);
            mPlayerMaxBufferPeriod = slesGetPlayerMaxBufferPeriod(sles_data);
            mPlayerStdDevBufferPeriod = Math.sqrt(slesGetPlayerVarianceBufferPeriod(sles_data));

            mPlayerCallbackTimes = slesGetPlayerCallbackTimeStamps(sles_data);
            mRecorderCallbackTimes = slesGetRecorderCallbackTimeStamps(sles_data);

            // get glitches data only for buffer test
            if (mTestType == Constant.LOOPBACK_PLUG_AUDIO_THREAD_TEST_TYPE_BUFFER_PERIOD) {
                mAllGlitches = mGlitchDetectionThread.getGlitches();
                mSamples = mGlitchDetectionThread.getWaveData();
                mGlitchingIntervalTooLong = mGlitchDetectionThread.getGlitchingIntervalTooLong();
                endDetecting();
            }

            if (mTestType == Constant.LOOPBACK_PLUG_AUDIO_THREAD_TEST_TYPE_LATENCY) {
                mCaptureHolder.captureState(0);
            }

            runDestroy(sles_data);

            final int maxTry = 20;
            int tryCount = 0;
            while (isDestroying) {
                try {
                    sleep(40);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                tryCount++;
                log("destroy try: " + tryCount);

                if (tryCount >= maxTry) {
                    hasDestroyingErrors = true;
                    log("WARNING: waited for max time to properly destroy JNI.");
                    break;
                }
            }
            log(String.format("after destroying. TotalSamplesRead = %d", totalSamplesRead));

            // for buffer test samples won't be read into here
            if (mTestType == Constant.LOOPBACK_PLUG_AUDIO_THREAD_TEST_TYPE_LATENCY
                && totalSamplesRead == 0) {
                //hasDestroyingErrors = true;
                log("Warning: Latency test reads no sample from native recorder!");
            }

            endTest();
        }
    }


    public void requestStopTest() {
        mIsRequestStop = true;
    }


    /** Set up parameters needed for GlitchDetectionThread, then create and run this thread. */
    private void setUpGlitchDetectionThread() {
        final int targetFFTMs = 20; // we want each FFT to cover 20ms of samples
        mFFTSamplingSize = targetFFTMs * mSamplingRate / Constant.MILLIS_PER_SECOND;
        // round to the nearest power of 2
        mFFTSamplingSize = (int) Math.pow(2, Math.round(Math.log(mFFTSamplingSize) / Math.log(2)));

        if (mFFTSamplingSize < 2) {
            mFFTSamplingSize = 2; // mFFTSamplingSize should be at least 2
        }
        mFFTOverlapSamples = mFFTSamplingSize / 2; // mFFTOverlapSamples is half of mFFTSamplingSize

        mGlitchDetectionThread = new GlitchDetectionThread(mFrequency1, mFrequency2, mSamplingRate,
            mFFTSamplingSize, mFFTOverlapSamples, mBufferTestDurationInSeconds,
            mBufferTestWavePlotDurationInSeconds, mPipeByteBuffer, mCaptureHolder);
        mGlitchDetectionThread.start();
    }


    public void endDetecting() {
        mPipeByteBuffer.flush();
        mPipeByteBuffer = null;
        mGlitchDetectionThread.requestStop();
        GlitchDetectionThread tempThread = mGlitchDetectionThread;
        mGlitchDetectionThread = null;
        try {
            tempThread.join(Constant.JOIN_WAIT_TIME_MS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }


    public void setMessageHandler(Handler messageHandler) {
        mMessageHandler = messageHandler;
    }


    private void runDestroy(final long sles_data) {
        isDestroying = true;

        //start thread
        final long local_sles_data = sles_data;
        Thread thread = new Thread(new Runnable() {
            public void run() {
                isDestroying = true;
                log("**Start runnable destroy");

                int status = slesDestroy(local_sles_data);
                log(String.format("**End runnable destroy sles delete status: %d", status));
                isDestroying = false;
            }
        });

        thread.start();
        log("end of runDestroy()");
    }


    /** not doing real work, just to keep consistency with LoopbackAudioThread. */
    public void runTest() {

    }


    /** not doing real work, just to keep consistency with LoopbackAudioThread. */
    public void runBufferTest() {

    }


    public void endTest() {
       log("--Ending capture test--");
       if (mMessageHandler != null) {
           Message msg = Message.obtain();
           if (hasDestroyingErrors) {
               switch (mTestType) {
                   case Constant.LOOPBACK_PLUG_AUDIO_THREAD_TEST_TYPE_LATENCY:
                       msg.what = LOOPBACK_NATIVE_AUDIO_THREAD_MESSAGE_LATENCY_REC_COMPLETE_ERRORS;
                       break;
                   case Constant.LOOPBACK_PLUG_AUDIO_THREAD_TEST_TYPE_BUFFER_PERIOD:
                       msg.what = LOOPBACK_NATIVE_AUDIO_THREAD_MESSAGE_BUFFER_REC_COMPLETE_ERRORS;
                       break;
               }
           } else if (mIsRequestStop) {
               switch (mTestType) {
                   case Constant.LOOPBACK_PLUG_AUDIO_THREAD_TEST_TYPE_LATENCY:
                       msg.what = LOOPBACK_NATIVE_AUDIO_THREAD_MESSAGE_LATENCY_REC_STOP;
                       break;
                   case Constant.LOOPBACK_PLUG_AUDIO_THREAD_TEST_TYPE_BUFFER_PERIOD:
                       msg.what = LOOPBACK_NATIVE_AUDIO_THREAD_MESSAGE_BUFFER_REC_STOP;
                       break;
               }
           } else {
               switch (mTestType) {
               case Constant.LOOPBACK_PLUG_AUDIO_THREAD_TEST_TYPE_LATENCY:
                   msg.what = LOOPBACK_NATIVE_AUDIO_THREAD_MESSAGE_LATENCY_REC_COMPLETE;
                   break;
               case Constant.LOOPBACK_PLUG_AUDIO_THREAD_TEST_TYPE_BUFFER_PERIOD:
                   msg.what = LOOPBACK_NATIVE_AUDIO_THREAD_MESSAGE_BUFFER_REC_COMPLETE;
                   break;
               }
           }

           mMessageHandler.sendMessage(msg);
       }
    }


    public void finish() {
        mIsRunning = false;
    }


    private static void log(String msg) {
        Log.v(TAG, msg);
    }


    double[] getWaveData() {
        return mSamples;
    }


    public int[] getRecorderBufferPeriod() {
        return mRecorderBufferPeriod;
    }

    public int getRecorderMaxBufferPeriod() {
        return mRecorderMaxBufferPeriod;
    }

    public double getRecorderStdDevBufferPeriod() {
        return mRecorderStdDevBufferPeriod;
    }

    public int[] getPlayerBufferPeriod() {
        return mPlayerBufferPeriod;
    }

    public int getPlayerMaxBufferPeriod() {
        return mPlayerMaxBufferPeriod;
    }

    public double getPlayerStdDevBufferPeriod() {
        return mPlayerStdDevBufferPeriod;
    }

    public int[] getNativeAllGlitches() {
        return mAllGlitches;
    }


    public boolean getGlitchingIntervalTooLong() {
        return mGlitchingIntervalTooLong;
    }


    public int getNativeFFTSamplingSize() {
        return mFFTSamplingSize;
    }


    public int getNativeFFTOverlapSamples() {
        return mFFTOverlapSamples;
    }


    public int getDurationInSeconds() {
        return mBufferTestDurationInSeconds;
    }

    public BufferCallbackTimes getPlayerCallbackTimes() {
        return mPlayerCallbackTimes;
    }

    public BufferCallbackTimes getRecorderCallbackTimes() {
        return mRecorderCallbackTimes;
    }
}
