/*
 * 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 com.android.tv.tuner.exoplayer.ac3;

import android.media.MediaFormat;

import com.google.android.exoplayer.audio.AudioTrack;

import java.nio.ByteBuffer;

/**
 * {@link AudioTrack} wrapper class for trickplay operations including FF/RW.
 * FF/RW trickplay operations do not need framework {@link AudioTrack}.
 * This wrapper class will do nothing in disabled status for those operations.
 */
public class AudioTrackWrapper {
    private final AudioTrack mAudioTrack = new AudioTrack();
    private int mAudioSessionID;
    private boolean mIsEnabled;

    AudioTrackWrapper() {
        mIsEnabled = true;
    }

    public void resetSessionId() {
        mAudioSessionID = AudioTrack.SESSION_ID_NOT_SET;
    }

    public boolean isInitialized() {
        return mIsEnabled && mAudioTrack.isInitialized();
    }

    public void restart() {
        if (mAudioTrack.isInitialized()) {
            mAudioTrack.release();
        }
        mIsEnabled = true;
        resetSessionId();
    }

    public void release()  {
        if (mAudioSessionID != AudioTrack.SESSION_ID_NOT_SET) {
            mAudioTrack.release();
        }
    }

    public void initialize() throws AudioTrack.InitializationException {
        if (!mIsEnabled) {
            return;
        }
        if (mAudioSessionID != AudioTrack.SESSION_ID_NOT_SET) {
            mAudioTrack.initialize(mAudioSessionID);
        } else {
            mAudioSessionID = mAudioTrack.initialize();
        }
    }

    public void reset() {
        if (!mIsEnabled) {
            return;
        }
        mAudioTrack.reset();
    }

    public boolean isEnded() {
        return !mIsEnabled || !mAudioTrack.hasPendingData();
    }

    public boolean isReady() {
        // In the case of not playing actual audio data, Audio track is always ready.
        return !mIsEnabled || mAudioTrack.hasPendingData();
    }

    public void play() {
        if (!mIsEnabled) {
            return;
        }
        mAudioTrack.play();
    }

    public void pause() {
        if (!mIsEnabled) {
            return;
        }
        mAudioTrack.pause();
    }

    public void setVolume(float volume) {
        if (!mIsEnabled) {
            return;
        }
        mAudioTrack.setVolume(volume);
    }

    public void reconfigure(MediaFormat format) {
        if (!mIsEnabled || format == null) {
            return;
        }
        String mimeType = format.getString(MediaFormat.KEY_MIME);
        int channelCount = format.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
        int sampleRate = format.getInteger(MediaFormat.KEY_SAMPLE_RATE);
        int pcmEncoding;
        try {
            pcmEncoding = format.getInteger(MediaFormat.KEY_PCM_ENCODING);
        } catch (Exception e) {
            pcmEncoding = com.google.android.exoplayer.MediaFormat.NO_VALUE;
        }
        // TODO: Handle non-AC3 or non-passthrough audio.
        if (MediaFormat.MIMETYPE_AUDIO_AC3.equalsIgnoreCase(mimeType) && channelCount != 2) {
            // Workarounds b/25955476.
            // Since all devices and platforms does not support passthrough for non-stereo AC3,
            // It is safe to fake non-stereo AC3 as AC3 stereo which is default passthrough mode.
            // In other words, the channel count should be always 2.
            channelCount = 2;
        }
        mAudioTrack.configure(mimeType, channelCount, sampleRate, pcmEncoding);
    }

    public void handleDiscontinuity() {
        if (!mIsEnabled) {
            return;
        }
        mAudioTrack.handleDiscontinuity();
    }

    public int handleBuffer(ByteBuffer buffer, int offset, int size, long presentationTimeUs)
            throws AudioTrack.WriteException {
        if (!mIsEnabled) {
            return AudioTrack.RESULT_BUFFER_CONSUMED;
        }
        return mAudioTrack.handleBuffer(buffer, offset, size, presentationTimeUs);
    }

    public void setStatus(boolean enable) {
        if (enable == mIsEnabled) {
            return;
        }
        mAudioTrack.reset();
        mIsEnabled = enable;
    }

    public boolean isEnabled() {
        return mIsEnabled;
    }

    // This should be used only in case of being enabled.
    public long getCurrentPositionUs(boolean isEnded) {
        return mAudioTrack.getCurrentPositionUs(isEnded);
    }
}
