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

//#define LOG_NDEBUG 0
#include <utility>
#define LOG_TAG "SoundPool::Stream"
#include <utils/Log.h>
#include <android/content/AttributionSourceState.h>

#include "Stream.h"

#include "StreamManager.h"

namespace android::soundpool {

Stream::~Stream()
{
    ALOGV("%s(%p)", __func__, this);
}

void Stream::autoPause()
{
    std::lock_guard lock(mLock);
    if (mState == PLAYING) {
        ALOGV("%s: track streamID: %d", __func__, (int)mStreamID);
        mState = PAUSED;
        mAutoPaused = true;
        if (mAudioTrack != nullptr) {
            mAudioTrack->pause();
        }
    }
}

void Stream::autoResume()
{
    std::lock_guard lock(mLock);
    if (mAutoPaused) {
        if (mState == PAUSED) {
            ALOGV("%s: track streamID: %d", __func__, (int)mStreamID);
            mState = PLAYING;
            if (mAudioTrack != nullptr) {
                mAudioTrack->start();
            }
        }
        mAutoPaused = false; // New for R: always reset autopause (consistent with API spec).
    }
}

void Stream::mute(bool muting)
{
    std::lock_guard lock(mLock);
    mMuted = muting;
    if (mAudioTrack != nullptr) {
        if (mMuted) {
            mAudioTrack->setVolume(0.0f, 0.0f);
        } else {
            mAudioTrack->setVolume(mLeftVolume, mRightVolume);
        }
    }
}

void Stream::pause(int32_t streamID)
{
    std::lock_guard lock(mLock);
    if (streamID == mStreamID) {
        if (mState == PLAYING) {
            ALOGV("%s: track streamID: %d", __func__, streamID);
            mState = PAUSED;
            if (mAudioTrack != nullptr) {
                mAudioTrack->pause();
            }
        }
    }
}

void Stream::resume(int32_t streamID)
{
    std::lock_guard lock(mLock);
    if (streamID == mStreamID) {
         if (mState == PAUSED) {
            ALOGV("%s: track streamID: %d", __func__, streamID);
            mState = PLAYING;
            if (mAudioTrack != nullptr) {
                mAudioTrack->start();
            }
            mAutoPaused = false; // TODO: is this right? (ambiguous per spec), move outside?
        }
    }
}

void Stream::setRate(int32_t streamID, float rate)
{
    std::lock_guard lock(mLock);
    if (streamID == mStreamID) {
        mRate = rate;
        if (mAudioTrack != nullptr && mSound != nullptr) {
            const auto sampleRate = (uint32_t)lround(double(mSound->getSampleRate()) * rate);
            mAudioTrack->setSampleRate(sampleRate);
        }
    }
}

void Stream::setVolume_l(float leftVolume, float rightVolume)
{
    mLeftVolume = leftVolume;
    mRightVolume = rightVolume;
    if (mAudioTrack != nullptr && !mMuted) {
        mAudioTrack->setVolume(leftVolume, rightVolume);
    }
}

void Stream::setVolume(int32_t streamID, float leftVolume, float rightVolume)
{
    std::lock_guard lock(mLock);
    if (streamID == mStreamID) {
        setVolume_l(leftVolume, rightVolume);
    }
}

void Stream::setPriority(int32_t streamID, int32_t priority)
{
    std::lock_guard lock(mLock);
    if (streamID == mStreamID) {
        mPriority = priority;
    }
}

void Stream::setLoop(int32_t streamID, int32_t loop)
{
    std::lock_guard lock(mLock);
    if (streamID == mStreamID) {
        if (mAudioTrack != nullptr && mSound != nullptr) {
            const uint32_t loopEnd = mSound->getSizeInBytes() / mSound->getChannelCount() /
                (mSound->getFormat() == AUDIO_FORMAT_PCM_16_BIT
                        ? sizeof(int16_t) : sizeof(uint8_t));
            mAudioTrack->setLoop(0, loopEnd, loop);
        }
        mLoop = loop;
    }
}

void Stream::setPlay(
        int32_t streamID, const std::shared_ptr<Sound> &sound, int32_t soundID,
        float leftVolume, float rightVolume, int32_t priority, int32_t loop, float rate)
{
    std::lock_guard lock(mLock);
    // We must be idle, or we must be repurposing a pending Stream.
    LOG_ALWAYS_FATAL_IF(mState != IDLE && mAudioTrack != nullptr, "State %d must be IDLE", mState);
    mSound = sound;
    mSoundID = soundID;
    mLeftVolume = leftVolume;
    mRightVolume = rightVolume;
    mPriority = priority;
    mLoop = loop;
    mRate = rate;
    mState = PLAYING;
    mAutoPaused = false;   // New for R (consistent with Java API spec).
    mStreamID = streamID;  // prefer this to be the last, as it is an atomic sync point
}

void Stream::setStopTimeNs(int64_t stopTimeNs)
{
    std::lock_guard lock(mLock);
    mStopTimeNs = stopTimeNs;
}

bool Stream::requestStop(int32_t streamID)
{
    std::lock_guard lock(mLock);
    if (streamID == mStreamID) {
        ALOGV("%s: track streamID: %d", __func__, streamID);
        if (mAudioTrack != nullptr) {
            if (mState == PLAYING && !mMuted && (mLeftVolume != 0.f || mRightVolume != 0.f)) {
                setVolume_l(0.f, 0.f);
                mStopTimeNs = systemTime() + kStopWaitTimeNs;
            } else {
                mStopTimeNs = systemTime();
            }
            return true; // must be queued on the restart list.
        }
        stop_l();
    }
    return false;
}

void Stream::stop()
{
    std::lock_guard lock(mLock);
    stop_l();
}

void Stream::stop_l()
{
    if (mState != IDLE) {
        ALOGV("%s: track(%p) streamID: %d", __func__, mAudioTrack.get(), (int)mStreamID);
        if (mAudioTrack != nullptr) {
            mAudioTrack->stop();
        }
        mSound.reset();
        mState = IDLE;
    }
}

void Stream::clearAudioTrack()
{
    sp<AudioTrack> release;  // release outside of lock.
    std::lock_guard lock(mLock);
    // This will invoke the destructor which waits for the AudioTrack thread to join,
    // and is currently the only safe way to ensure there are no callbacks afterwards.
    release = mAudioTrack;  // or std::swap if we had move semantics.
    mAudioTrack.clear();
}

Stream* Stream::getPairStream() const
{
   return mStreamManager->getPairStream(this);
}

Stream* Stream::playPairStream(std::vector<std::any>& garbage, int32_t playerIId) {
    Stream* pairStream = getPairStream();
    LOG_ALWAYS_FATAL_IF(pairStream == nullptr, "No pair stream!");
    {
        ALOGV("%s: track streamID: %d", __func__, (int)getStreamID());
        // TODO: Do we really want to force a simultaneous synchronization between
        // the stream and its pair?

        // note locking order - the paired stream is obtained before the queued stream.
        // we can invert the locking order, but it is slightly more optimal to do it this way.
        std::lock_guard lockp(pairStream->mLock);
        if (pairStream->mSound == nullptr) {
            return nullptr; // no pair sound
        }
        {
            std::lock_guard lock(mLock);
            LOG_ALWAYS_FATAL_IF(mState != IDLE, "State: %d must be IDLE", mState);
            // TODO: do we want a specific set() here?
            pairStream->mAudioTrack = mAudioTrack;
            pairStream->mSoundID = mSoundID; // optimization to reuse AudioTrack.
            pairStream->mToggle = mToggle;
            pairStream->mAutoPaused = mAutoPaused; // save autopause state
            pairStream->mMuted = mMuted;
            mAudioTrack.clear();  // the pair owns the audiotrack.
            mSound.reset();
            mSoundID = 0;
        }
        // TODO: do we need a specific play_l() anymore?
        const int pairState = pairStream->mState;
        pairStream->play_l(pairStream->mSound, pairStream->mStreamID,
                pairStream->mLeftVolume, pairStream->mRightVolume, pairStream->mPriority,
                pairStream->mLoop, pairStream->mRate, garbage, playerIId);
        if (pairStream->mState == IDLE) {
            return nullptr; // AudioTrack error
        }
        if (pairState == PAUSED) {  // reestablish pause
            pairStream->mState = PAUSED;
            pairStream->mAudioTrack->pause();
        }
    }
    return pairStream;
}

void Stream::play_l(const std::shared_ptr<Sound>& sound, int32_t nextStreamID,
        float leftVolume, float rightVolume, int32_t priority, int32_t loop, float rate,
        std::vector<std::any>& garbage, int32_t playerIId)
{
    ALOGV("%s(%p)(soundID=%d, streamID=%d, leftVolume=%f, rightVolume=%f,"
            " priority=%d, loop=%d, rate=%f, playerIId=%d)",
            __func__, this, sound->getSoundID(), nextStreamID, leftVolume, rightVolume,
            priority, loop, rate, playerIId);

    // initialize track
    const int32_t channelCount = sound->getChannelCount();
    const auto sampleRate = (uint32_t)lround(double(sound->getSampleRate()) * rate);
    size_t frameCount = 0;

    if (loop) {
        const audio_format_t format = sound->getFormat();
        const size_t frameSize = audio_is_linear_pcm(format)
                ? channelCount * audio_bytes_per_sample(format) : 1;
        frameCount = sound->getSizeInBytes() / frameSize;
    }

    if (mAudioTrack != nullptr) {
        if (mSoundID == sound->getSoundID()
                && mAudioTrack->setSampleRate(sampleRate) == NO_ERROR) {
            // Reuse the old track if the soundID matches.
            // the sample rate may fail to change if the audio track is a fast track.
            ALOGV("%s: reusing track %p for sound %d",
                    __func__, mAudioTrack.get(), sound->getSoundID());
        } else {
            // If reuse not possible, move mAudioTrack to garbage, set to nullptr.
            garbage.emplace_back(std::move(mAudioTrack));
            mAudioTrack.clear(); // move should have cleared the sp<>, but we clear just in case.
        }
    }
    if (mAudioTrack == nullptr) {
        // mToggle toggles each time a track is started on a given stream.
        // This enables the detection of callbacks received from the old
        // audio track while the new one is being started and avoids processing them with
        // wrong audio audio buffer size  (mAudioBufferSize)
        auto toggle = mToggle ^ 1;
        // NOLINTNEXTLINE(performance-no-int-to-ptr)
        audio_channel_mask_t soundChannelMask = sound->getChannelMask();
        // When sound contains a valid channel mask, use it as is.
        // Otherwise, use stream count to calculate channel mask.
        audio_channel_mask_t channelMask = soundChannelMask != AUDIO_CHANNEL_NONE
                ? soundChannelMask : audio_channel_out_mask_from_count(channelCount);

        // do not create a new audio track if current track is compatible with sound parameters

        android::content::AttributionSourceState attributionSource;
        attributionSource.packageName = mStreamManager->getOpPackageName();
        attributionSource.token = sp<BBinder>::make();
        mCallback =  sp<StreamCallback>::make(this, toggle),
        // TODO b/182469354 make consistent with AudioRecord, add util for native source
        mAudioTrack = new AudioTrack(AUDIO_STREAM_DEFAULT, sampleRate, sound->getFormat(),
                channelMask, sound->getIMemory(), AUDIO_OUTPUT_FLAG_NONE,
                mCallback,
                0 /*default notification frames*/, AUDIO_SESSION_ALLOCATE,
                AudioTrack::TRANSFER_DEFAULT,
                nullptr /*offloadInfo*/, attributionSource,
                mStreamManager->getAttributes(),
                false /*doNotReconnect*/, 1.0f /*maxRequiredSpeed*/);
        // Set caller name so it can be logged in destructor.
        // MediaMetricsConstants.h: AMEDIAMETRICS_PROP_CALLERNAME_VALUE_SOUNDPOOL
        mAudioTrack->setCallerName("soundpool");

        if (playerIId != PLAYER_PIID_INVALID) {
            mAudioTrack->setPlayerIId(playerIId);
        }

        if (status_t status = mAudioTrack->initCheck();
            status != NO_ERROR) {
            ALOGE("%s: error %d creating AudioTrack", __func__, status);
            // TODO: should we consider keeping the soundID and reusing the old track?
            mState = IDLE;
            mSoundID = 0;
            mSound.reset();
            garbage.emplace_back(std::move(mAudioTrack)); // remove mAudioTrack.
            mAudioTrack.clear(); // move should have cleared the sp<>, but we clear just in case.
            return;
        }
        // From now on, AudioTrack callbacks received with previous toggle value will be ignored.
        mToggle = toggle;
        ALOGV("%s: using new track %p for sound %d",
                __func__, mAudioTrack.get(), sound->getSoundID());
    }
    if (mMuted) {
        mAudioTrack->setVolume(0.f, 0.f);
    } else {
        mAudioTrack->setVolume(leftVolume, rightVolume);
    }
    mAudioTrack->setLoop(0, frameCount, loop);
    mAudioTrack->start();
    mSound = sound;
    mSoundID = sound->getSoundID();
    mPriority = priority;
    mLoop = loop;
    mLeftVolume = leftVolume;
    mRightVolume = rightVolume;
    mRate = rate;
    mState = PLAYING;
    mStopTimeNs = 0;
    mStreamID = nextStreamID;  // prefer this to be the last, as it is an atomic sync point
}

int Stream::getCorrespondingStreamID() {
    std::lock_guard lock(mLock);
    return static_cast<int>(mAudioTrack ? mStreamID : getPairStream()->mStreamID);
}

size_t Stream::StreamCallback::onMoreData(const AudioTrack::Buffer&) {
    ALOGW("%s streamID %d Unexpected EVENT_MORE_DATA for static track",
            __func__, mStream->getCorrespondingStreamID());
    return 0;
}

void Stream::StreamCallback::onUnderrun() {
    ALOGW("%s streamID %d Unexpected EVENT_UNDERRUN for static track",
            __func__, mStream->getCorrespondingStreamID());
}

void Stream::StreamCallback::onLoopEnd(int32_t) {
    ALOGV("%s streamID %d EVENT_LOOP_END", __func__, mStream->getCorrespondingStreamID());
}

void Stream::StreamCallback::onMarker(uint32_t) {
    ALOGW("%s streamID %d Unexpected EVENT_MARKER for static track",
            __func__, mStream->getCorrespondingStreamID());
}

void Stream::StreamCallback::onNewPos(uint32_t) {
    ALOGW("%s streamID %d Unexpected EVENT_NEW_POS for static track",
            __func__, mStream->getCorrespondingStreamID());
}

void Stream::StreamCallback::onBufferEnd() {
    mStream->onBufferEnd(mToggle, 0);
}

void Stream::StreamCallback::onNewIAudioTrack() {
    ALOGV("%s streamID %d NEW_IAUDIOTRACK", __func__, mStream->getCorrespondingStreamID());
}

void Stream::StreamCallback::onStreamEnd() {
    ALOGW("%s streamID %d Unexpected EVENT_STREAM_END for static track",
            __func__, mStream->getCorrespondingStreamID());
}

size_t Stream::StreamCallback::onCanWriteMoreData(const AudioTrack::Buffer&) {
    ALOGW("%s streamID %d Unexpected EVENT_CAN_WRITE_MORE_DATA for static track",
            __func__, mStream->getCorrespondingStreamID());
    return 0;
}

void Stream::onBufferEnd(int toggle, int tries)
{
    int32_t activeStreamIDToRestart = 0;
    {
        std::unique_lock lock(mLock);
        ALOGV("%s track(%p) streamID %d", __func__, mAudioTrack.get(), (int)mStreamID);

        if (mAudioTrack == nullptr) {
            // The AudioTrack is either with this stream or its pair.
            // if this swaps a few times, the toggle is bound to be wrong, so we fail then.
            //
            // TODO: Modify AudioTrack callbacks to avoid the hacky toggle and retry
            // logic here.
            if (tries < 3) {
                lock.unlock();
                ALOGV("%s streamID %d going to pair stream", __func__, (int)mStreamID);
                getPairStream()->onBufferEnd(toggle, tries + 1);
            } else {
                ALOGW("%s streamID %d cannot find track", __func__, (int)mStreamID);
            }
            return;
        }
        if (mToggle != toggle) {
            ALOGD("%s streamID %d wrong toggle", __func__, (int)mStreamID);
            return;
        }
        ALOGV("%s streamID %d EVENT_BUFFER_END", __func__, (int)mStreamID);
        if (mState != IDLE) {
            activeStreamIDToRestart = mStreamID;
            mStopTimeNs = systemTime();
        }
    } // lock ends here.  This is on the callback thread, no need to be precise.
    if (activeStreamIDToRestart > 0) {
        // Restart only if a particular streamID is still current and active.
        ALOGV("%s: moveToRestartQueue %d", __func__, activeStreamIDToRestart);
        mStreamManager->moveToRestartQueue(this, activeStreamIDToRestart);
    }
}

void Stream::dump() const
{
    // TODO: consider std::try_lock() - ok for now for ALOGV.
    ALOGV("mPairStream=%p, mState=%d, mStreamID=%d, mSoundID=%d, mPriority=%d, mLoop=%d",
            getPairStream(), mState, (int)getStreamID(), getSoundID(), mPriority, mLoop);
}

} // namespace android::soundpool
