//Copyright 2012 James Falcon
//
//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.

/* Minor modifications by Martin Fietz <Martin.Fietz@gmail.com>
 * The original source can be found here:
 * https://github.com/TheRealFalcon/Prestissimo/blob/master/src/com/falconware/prestissimo/Track.java
 */

package org.antennapod.audio;

import android.annotation.TargetApi;
import android.content.Context;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.media.MediaCodec;
import android.media.MediaExtractor;
import android.media.MediaFormat;
import android.net.Uri;
import android.os.Build;
import android.os.PowerManager;
import android.util.Log;

import org.vinuxproject.sonic.Sonic;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.concurrent.locks.ReentrantLock;

@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public class SonicAudioPlayer extends AbstractAudioPlayer {

    private static final String TAG = SonicAudioPlayer.class.getSimpleName();

    protected final MediaPlayer mMediaPlayer;
    private AudioTrack mTrack;
    private int mBufferSize;
    private Sonic mSonic;
    private MediaExtractor mExtractor;
    private MediaCodec mCodec;
    private Thread mDecoderThread;
    private String mPath;
    private Uri mUri;
    private final ReentrantLock mLock;
    private final Object mDecoderLock;
    private boolean mContinue;
    private boolean mIsDecoding;
    private long mDuration;
    private float mCurrentSpeed;
    private float mCurrentPitch;
    private int mCurrentState;
    private final Context mContext;
    private PowerManager.WakeLock mWakeLock = null;
    private boolean mDownMix;

    private final static String TAG_TRACK = "SonicTrack";

    private final static int STATE_IDLE = 0;
    private final static int STATE_INITIALIZED = 1;
    private final static int STATE_PREPARING = 2;
    private final static int STATE_PREPARED = 3;
    private final static int STATE_STARTED = 4;
    private final static int STATE_PAUSED = 5;
    private final static int STATE_STOPPED = 6;
    private final static int STATE_PLAYBACK_COMPLETED = 7;
    private final static int STATE_END = 8;
    private final static int STATE_ERROR = 9;

    public SonicAudioPlayer(MediaPlayer owningMediaPlayer, Context context) {
        super(owningMediaPlayer, context);
        mMediaPlayer = owningMediaPlayer;
        mCurrentState = STATE_IDLE;
        mCurrentSpeed = 1.0f;
        mCurrentPitch = 1.0f;
        mContinue = false;
        mIsDecoding = false;
        mContext = context;
        mPath = null;
        mUri = null;
        mLock = new ReentrantLock();
        mDecoderLock = new Object();
        mDownMix = false;
    }

    @Override
    public int getAudioSessionId() {
        if(mTrack == null) {
            return 0;
        } else {
            return mTrack.getAudioSessionId();
        }
    }

    @Override
    public boolean canSetPitch() {
        return true;
    }

    @Override
    public boolean canSetSpeed() {
        return true;
    }

    @Override
    public float getCurrentPitchStepsAdjustment() {
        return mCurrentPitch;
    }

    public int getCurrentPosition() {
        switch (mCurrentState) {
            case STATE_ERROR:
            case STATE_IDLE:
            case STATE_INITIALIZED:
                return 0;
            default:
                return (int) (mExtractor.getSampleTime() / 1000);
        }
    }

    @Override
    public float getCurrentSpeedMultiplier() {
        return mCurrentSpeed;
    }

    @Override
    public boolean canDownmix() {
        return true;
    }

    @Override
    public void setDownmix(boolean enable) {
        mDownMix = enable;
    }

    public int getDuration() {
        switch (mCurrentState) {
            case STATE_INITIALIZED:
            case STATE_IDLE:
            case STATE_ERROR:
                error();
                break;
            default:
                return (int) (mDuration / 1000);
        }
        return 0;
    }

    @Override
    public float getMaxSpeedMultiplier() {
        return 4.0f;
    }

    @Override
    public float getMinSpeedMultiplier() {
        return 0.5f;
    }

    @Override
    public boolean isLooping() {
        return false;
    }

    public boolean isPlaying() {
        switch (mCurrentState) {
            case STATE_ERROR:
                error();
                break;
            default:
                return mCurrentState == STATE_STARTED;
        }
        return false;
    }

    public void pause() {
        Log.d(TAG, "pause(), current state: " + mCurrentState);
        switch (mCurrentState) {
            case STATE_PREPARED:
                Log.d(TAG_TRACK, "Prepared, ignore pause()");
                break;
            case STATE_STARTED:
            case STATE_PAUSED:
                mTrack.pause();
                mCurrentState = STATE_PAUSED;
                Log.d(TAG_TRACK, "State changed to STATE_PAUSED");
                break;
            default:
                error();
        }
    }

    public void prepare() {
        Log.d(TAG, "prepare(), current state: " + mCurrentState);
        switch (mCurrentState) {
            case STATE_INITIALIZED:
            case STATE_STOPPED:
                try {
                    initStream();
                } catch (IOException e) {
                    Log.e(TAG_TRACK, "Failed setting data source!", e);
                    error();
                    return;
                }
                mCurrentState = STATE_PREPARED;
                Log.d(TAG_TRACK, "State changed to STATE_PREPARED");
                if(owningMediaPlayer.onPreparedListener != null) {
                    owningMediaPlayer.onPreparedListener.onPrepared(owningMediaPlayer);
                }
                break;
            default:
                error();
        }
    }

    public void prepareAsync() {
        switch (mCurrentState) {
            case STATE_INITIALIZED:
            case STATE_STOPPED:
                mCurrentState = STATE_PREPARING;
                Log.d(TAG_TRACK, "State changed to STATE_PREPARING");

                Thread t = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            initStream();
                        } catch (IOException e) {
                            Log.e(TAG_TRACK, "Failed setting data source!", e);
                            error();
                            return;
                        }
                        if (mCurrentState != STATE_ERROR) {
                            mCurrentState = STATE_PREPARED;
                            Log.d(TAG_TRACK, "State changed to STATE_PREPARED");
                        }
                        if(owningMediaPlayer.onPreparedListener != null) {
                            owningMediaPlayer.onPreparedListener.onPrepared(owningMediaPlayer);
                        }
                    }
                });
                t.setDaemon(true);
                t.start();
                break;
            default:
                error();
        }
    }

    public void stop() {
        switch (mCurrentState) {
            case STATE_PREPARED:
            case STATE_STARTED:
            case STATE_STOPPED:
            case STATE_PAUSED:
            case STATE_PLAYBACK_COMPLETED:
                mCurrentState = STATE_STOPPED;
                Log.d(TAG_TRACK, "State changed to STATE_STOPPED");
                mContinue = false;
                mTrack.pause();
                mTrack.flush();
                break;
            default:
                error();
        }
    }

    public void start() {
        switch (mCurrentState) {
            case STATE_PLAYBACK_COMPLETED:
                try {
                    initStream();
                } catch (IOException e) {
                    Log.e(TAG, "initStream() failed");
                    error();
                    return;
                }
                // deliberate fallthrough
            case STATE_PREPARED:
                mCurrentState = STATE_STARTED;
                Log.d(TAG, "State changed to STATE_STARTED");
                mContinue = true;
                mTrack.play();
                decode();
            case STATE_STARTED:
                break;
            case STATE_PAUSED:
                mCurrentState = STATE_STARTED;
                Log.d(TAG, "State changed to STATE_STARTED");
                synchronized (mDecoderLock) {
                    mDecoderLock.notify();
                }
                mTrack.play();
                break;
            default:
                mCurrentState = STATE_ERROR;
                Log.d(TAG, "State changed to STATE_ERROR in start");
                if (mTrack != null) {
                    error();
                } else {
                    Log.d("start", "Attempting to start while in idle after construction. " +
                            "Not allowed by no callbacks called");
                }
        }
    }

    public void release() {
        reset();
        mCurrentState = STATE_END;
    }

    public void reset() {
        mLock.lock();
        mContinue = false;
        try {
            if (mDecoderThread != null
                    && mCurrentState != STATE_PLAYBACK_COMPLETED) {
                while (mIsDecoding) {
                    synchronized (mDecoderLock) {
                        mDecoderLock.notify();
                        mDecoderLock.wait();
                    }
                }
            }
        } catch (InterruptedException e) {
            Log.e(TAG_TRACK,
                    "Interrupted in reset while waiting for decoder thread to stop.",
                    e);
        }
        if (mCodec != null) {
            mCodec.release();
            mCodec = null;
        }
        if (mExtractor != null) {
            mExtractor.release();
            mExtractor = null;
        }
        if (mTrack != null) {
            mTrack.release();
            mTrack = null;
        }
        mCurrentState = STATE_IDLE;
        Log.d(TAG_TRACK, "State changed to STATE_IDLE");
        mLock.unlock();
    }

    public void seekTo(final int msec) {
        boolean playing = false;
        switch (mCurrentState) {
            case STATE_STARTED:
                playing = true;
                pause();
            case STATE_PREPARED:
            case STATE_PAUSED:
            case STATE_PLAYBACK_COMPLETED:
                mLock.lock();
                if (mTrack == null) {
                    return;
                }
                mTrack.flush();
                mExtractor.seekTo(((long) msec * 1000), MediaExtractor.SEEK_TO_PREVIOUS_SYNC);
                Log.d(TAG, "seek completed, position: " + (mExtractor.getSampleTime() / 1000L));
                if (owningMediaPlayer.onSeekCompleteListener != null) {
                    owningMediaPlayer.onSeekCompleteListener.onSeekComplete(owningMediaPlayer);
                }
                mLock.unlock();
                if (playing) {
                    start();
                }
                break;
            default:
                error();
        }
    }

    @Override
    public void setAudioStreamType(int streamtype) {
        return;
    }

    @Override
    public void setEnableSpeedAdjustment(boolean enableSpeedAdjustment) {
        return;
    }

    @Override
    public void setLooping(boolean loop) {
        return;
    }

    @Override
    public void setPitchStepsAdjustment(float pitchSteps) {
        mCurrentPitch += pitchSteps;
    }

    @Override
    public void setPlaybackPitch(float f) {
        mCurrentSpeed = f;
    }

    @Override
    public void setPlaybackSpeed(float f) {
        mCurrentSpeed = f;
    }

    @Override
    public void setDataSource(String path) {
        switch (mCurrentState) {
            case STATE_IDLE:
                mPath = path;
                mCurrentState = STATE_INITIALIZED;
                Log.d(TAG_TRACK, "Moving state to STATE_INITIALIZED");
                break;
            default:
                error();
        }
    }

    @Override
    public void setDataSource(Context context, Uri uri) {
        switch (mCurrentState) {
            case STATE_IDLE:
                mUri = uri;
                mCurrentState = STATE_INITIALIZED;
                Log.d(TAG_TRACK, "Moving state to STATE_INITIALIZED");
                break;
            default:
                error();
        }
    }

    public void setDownMix(boolean downmix) {
        mDownMix = downmix;
    }

    @SuppressWarnings("deprecation")
    @Override
    public void setVolume(float leftVolume, float rightVolume) {
        // Pass call directly to AudioTrack if available.
        if (null != mTrack) {
            mTrack.setStereoVolume(leftVolume, rightVolume);
        }
    }

    @Override
    public void setWakeMode(Context context, int mode) {
        boolean wasHeld = false;
        if (mWakeLock != null) {
            if (mWakeLock.isHeld()) {
                wasHeld = true;
                mWakeLock.release();
            }
            mWakeLock = null;
        }

        if(mode > 0) {
            PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
            mWakeLock = pm.newWakeLock(mode, this.getClass().getName());
            mWakeLock.setReferenceCounted(false);
            if (wasHeld) {
                mWakeLock.acquire();
            }
        }
    }

    public void error() {
        error(0);
    }

    public void error(int extra) {
        if(mCurrentState == STATE_ERROR) {
            return;
        }
        Log.e(TAG_TRACK, "Moved to error state!");
        mCurrentState = STATE_ERROR;
        if(owningMediaPlayer.onErrorListener != null) {
            boolean handled = owningMediaPlayer.onErrorListener.onError(owningMediaPlayer, 0, extra);
            if (!handled && owningMediaPlayer.onCompletionListener != null) {
                owningMediaPlayer.onCompletionListener.onCompletion(owningMediaPlayer);
            }
        }
    }

    private int findFormatFromChannels(int numChannels) {
        switch (numChannels) {
            case 1:
                return AudioFormat.CHANNEL_OUT_MONO;
            case 2:
                return AudioFormat.CHANNEL_OUT_STEREO;
            case 3:
                return AudioFormat.CHANNEL_OUT_STEREO | AudioFormat.CHANNEL_OUT_FRONT_CENTER;
            case 4:
                return AudioFormat.CHANNEL_OUT_QUAD;
            case 5:
                return AudioFormat.CHANNEL_OUT_QUAD | AudioFormat.CHANNEL_OUT_FRONT_CENTER;
            case 6:
                return AudioFormat.CHANNEL_OUT_5POINT1;
            case 7:
                return AudioFormat.CHANNEL_OUT_5POINT1 | AudioFormat.CHANNEL_OUT_BACK_CENTER;
            case 8:
                if (Build.VERSION.SDK_INT >= 23) {
                    return AudioFormat.CHANNEL_OUT_7POINT1_SURROUND;
                } else {
                    return -1;
                }
            default:
                return -1; // Error
        }
    }

    public void initStream() throws IOException {
        mLock.lock();
        mExtractor = new MediaExtractor();
        if (mPath != null) {
            mExtractor.setDataSource(mPath);
        } else if (mUri != null) {
            mExtractor.setDataSource(mContext, mUri, null);
        } else {
            throw new IOException();
        }

        int trackNum = -1;
        for(int i=0; i < mExtractor.getTrackCount(); i++) {
            final MediaFormat oFormat = mExtractor.getTrackFormat(i);
            String mime = oFormat.getString(MediaFormat.KEY_MIME);
            if(trackNum < 0 &&  mime.startsWith("audio/")) {
                trackNum = i;
            } else {
                mExtractor.unselectTrack(i);
            }
        }

        if(trackNum < 0) {
            throw new IOException("No audio track found");
        }

        final MediaFormat oFormat = mExtractor.getTrackFormat(trackNum);
        try {
            int sampleRate = oFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE);
            int channelCount = oFormat.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
            final String mime = oFormat.getString(MediaFormat.KEY_MIME);
            mDuration = oFormat.getLong(MediaFormat.KEY_DURATION);

            Log.v(TAG_TRACK, "Sample rate: " + sampleRate);
            Log.v(TAG_TRACK, "Channel count: " + channelCount);
            Log.v(TAG_TRACK, "Mime type: " + mime);
            Log.v(TAG_TRACK, "Duration: " + mDuration);

            initDevice(sampleRate, channelCount);
            mExtractor.selectTrack(trackNum);
            mCodec = MediaCodec.createDecoderByType(mime);
            mCodec.configure(oFormat, null, null, 0);
        } catch(Throwable th) {
            Log.e(TAG, Log.getStackTraceString(th));
            error();
        }
        mLock.unlock();
    }

    private void initDevice(int sampleRate, int numChannels) {
        mLock.lock();
        final int format = findFormatFromChannels(numChannels);
        int oldBufferSize = mBufferSize;
        mBufferSize = AudioTrack.getMinBufferSize(sampleRate, format, AudioFormat.ENCODING_PCM_16BIT);
        if(mBufferSize != oldBufferSize) {
            if (mTrack != null) {
                mTrack.release();
            }
            mTrack = createAudioTrack(sampleRate, format, mBufferSize);
        }
        mSonic = new Sonic(sampleRate, numChannels);
        mLock.unlock();
    }

    private AudioTrack createAudioTrack(int sampleRate,
                                        int channelConfig,
                                        int minBufferSize) {
        for (int i = 4; i >= 1; i--) {
            int bufferSize = minBufferSize * i;

            AudioTrack audioTrack = null;
            try {
                audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate,
                        channelConfig, AudioFormat.ENCODING_PCM_16BIT, bufferSize,
                        AudioTrack.MODE_STREAM);
                if (audioTrack.getState() == AudioTrack.STATE_INITIALIZED) {
                    mBufferSize = bufferSize;
                    return audioTrack;
                } else {
                    audioTrack.release();
                }
            } catch (IllegalArgumentException e) {
                Log.e(TAG, Log.getStackTraceString(e));
                if (audioTrack != null) {
                    audioTrack.release();
                }
            }
        }
        throw new IllegalStateException("Could not create buffer for AudioTrack");
    }


    @SuppressWarnings("deprecation")
    public void decode() {
        mDecoderThread = new Thread(new Runnable() {

            private int currHeadPos;

            @Override
            public void run() {

                mIsDecoding = true;
                mCodec.start();

                ByteBuffer[] inputBuffers = mCodec.getInputBuffers();
                ByteBuffer[] outputBuffers = mCodec.getOutputBuffers();

                boolean sawInputEOS = false;
                boolean sawOutputEOS = false;

                while (!sawInputEOS && !sawOutputEOS && mContinue) {
                    currHeadPos = mTrack.getPlaybackHeadPosition();
                    if (mCurrentState == STATE_PAUSED) {
                        System.out.println("Decoder changed to PAUSED");
                        try {
                            synchronized (mDecoderLock) {
                                mDecoderLock.wait();
                                System.out.println("Done with wait");
                            }
                        } catch (InterruptedException e) {
                            // Purposely not doing anything here
                        }
                        continue;
                    }

                    if (null != mSonic) {
                        mSonic.setSpeed(mCurrentSpeed);
                        mSonic.setPitch(mCurrentPitch);
                    }

                    int inputBufIndex = mCodec.dequeueInputBuffer(200);
                    if (inputBufIndex >= 0) {
                        ByteBuffer dstBuf = inputBuffers[inputBufIndex];
                        int sampleSize = mExtractor.readSampleData(dstBuf, 0);
                        long presentationTimeUs = 0;
                        if (sampleSize < 0) {
                            sawInputEOS = true;
                            sampleSize = 0;
                        } else {
                            presentationTimeUs = mExtractor.getSampleTime();
                        }
                        mCodec.queueInputBuffer(
                                inputBufIndex,
                                0,
                                sampleSize,
                                presentationTimeUs,
                                sawInputEOS ? MediaCodec.BUFFER_FLAG_END_OF_STREAM : 0);
                        if (!sawInputEOS) {
                            mExtractor.advance();
                        }
                    }

                    final MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
                    byte[] modifiedSamples = new byte[info.size];

                    int res;
                    do {
                        res = mCodec.dequeueOutputBuffer(info, 200);
                        if (res >= 0) {
                            int outputBufIndex = res;
                            final byte[] chunk = new byte[info.size];
                            outputBuffers[res].get(chunk);
                            outputBuffers[res].clear();

                            if (chunk.length > 0) {
                                mSonic.writeBytesToStream(chunk, chunk.length);
                            } else {
                                mSonic.flushStream();
                            }
                            int available = mSonic.samplesAvailable();
                            if (available > 0) {
                                if (modifiedSamples.length < available) {
                                    modifiedSamples = new byte[available];
                                }
                                if (mDownMix && mSonic.getNumChannels() == 2) {
                                    int maxBytes = (available / 4) * 4;
                                    mSonic.readBytesFromStream(modifiedSamples, maxBytes);

                                    for (int i = 0; (i + 3) < modifiedSamples.length; i += 4) {
                                        short left = (short) ((modifiedSamples[i] & 0xff) | (modifiedSamples[i + 1] << 8));
                                        short right = (short) ((modifiedSamples[i + 2] & 0xff) | (modifiedSamples[i + 3] << 8));
                                        short value = (short) (0.5 * left + 0.5 * right);

                                        modifiedSamples[i] = (byte) (value & 0xff);
                                        modifiedSamples[i + 1] = (byte) (value >> 8);
                                        modifiedSamples[i + 2] = (byte) (value & 0xff);
                                        modifiedSamples[i + 3] = (byte) (value >> 8);
                                    }
                                    mTrack.write(modifiedSamples, 0, maxBytes);
                                } else {
                                    mSonic.readBytesFromStream(modifiedSamples, available);
                                    mTrack.write(modifiedSamples, 0, available);
                                }
                            }

                            mCodec.releaseOutputBuffer(outputBufIndex, false);

                            if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
                                sawOutputEOS = true;
                            }
                        } else if (res == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
                            outputBuffers = mCodec.getOutputBuffers();
                            Log.d("PCM", "Output buffers changed");
                        } else if (res == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
                            mTrack.stop();
                            mLock.lock();
                            mTrack.release();
                            final MediaFormat oformat = mCodec.getOutputFormat();
                            Log.d("PCM", "Output format has changed to" + oformat);
                            initDevice(
                                    oformat.getInteger(MediaFormat.KEY_SAMPLE_RATE),
                                    oformat.getInteger(MediaFormat.KEY_CHANNEL_COUNT));
                            outputBuffers = mCodec.getOutputBuffers();
                            mTrack.play();
                            mLock.unlock();
                        }
                    } while (res == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED
                            || res == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED);
                }
                Log.d(TAG_TRACK, "Decoding loop exited. Stopping codec and track");
                Log.d(TAG_TRACK, "Duration: " + (int) (mDuration / 1000));
                Log.d(TAG_TRACK, "Current position: " + (int) (mExtractor.getSampleTime() / 1000));
                mCodec.stop();

                // wait for track to finish playing
                int lastHeadPos;
                do {
                    lastHeadPos = currHeadPos;
                    try {
                        Thread.sleep(100);
                        currHeadPos = mTrack.getPlaybackHeadPosition();
                    } catch (InterruptedException e) { /* ignore */ }
                } while(currHeadPos != lastHeadPos);
                mTrack.stop();

                Log.d(TAG_TRACK, "Stopped codec and track");
                Log.d(TAG_TRACK, "Current position: " + (int) (mExtractor.getSampleTime() / 1000));
                mIsDecoding = false;
                if (mContinue && (sawInputEOS || sawOutputEOS)) {
                    mCurrentState = STATE_PLAYBACK_COMPLETED;
                    if (owningMediaPlayer.onCompletionListener != null) {
                        Thread t = new Thread(new Runnable() {
                            @Override
                            public void run() {
                                owningMediaPlayer.onCompletionListener.onCompletion(owningMediaPlayer);

                            }
                        });
                        t.setDaemon(true);
                        t.start();
                    }
                } else {
                    Log.d(TAG_TRACK, "Loop ended before saw input eos or output eos");
                    Log.d(TAG_TRACK, "sawInputEOS: " + sawInputEOS);
                    Log.d(TAG_TRACK, "sawOutputEOS: " + sawOutputEOS);
                }
                synchronized (mDecoderLock) {
                    mDecoderLock.notifyAll();
                }
            }
        });
        mDecoderThread.setDaemon(true);
        mDecoderThread.start();
    }

}
