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

#pragma once

#include "Sound.h"

#include <android-base/thread_annotations.h>
#include <audio_utils/clock.h>
#include <media/AudioTrack.h>

namespace android::soundpool {

// This is the amount of time to wait after stop is called when stealing an
// AudioTrack to allow the sound to ramp down.  If this is 0, glitches
// may occur when stealing an AudioTrack.
inline constexpr int64_t kStopWaitTimeNs = 20 * NANOS_PER_MILLISECOND;

inline constexpr size_t kCacheLineSize = 64; /* std::hardware_constructive_interference_size */

class StreamManager; // forward decl

/**
 * A Stream is associated with a StreamID exposed to the app to play a Sound.
 *
 * The Stream uses monitor locking strategy on mLock.
 * https://en.wikipedia.org/wiki/Monitor_(synchronization)
 *
 * where public methods are guarded by a lock (as needed)
 *
 * For Java equivalent APIs, see
 * https://developer.android.com/reference/android/media/SoundPool
 *
 * Streams are paired by the StreamManager, so one stream in the pair may be "stopping"
 * while the other stream of the pair has been prepared to run
 * (and the streamID returned to the app) pending its pair to be stopped.
 * The pair of a Stream may be obtained by calling getPairStream(),
 * where this->getPairStream()->getPairStream() == this; (pair is a commutative relationship).
 *
 * playPairStream() and getPairPriority() access the paired stream.
 * See also StreamManager.h for details of physical layout implications of paired streams.
 */
class alignas(kCacheLineSize) Stream {
public:
    enum state { IDLE, PAUSED, PLAYING };
    // The PAUSED, PLAYING state directly corresponds to the AudioTrack state of an active Stream.
    //
    // The IDLE state indicates an inactive Stream.   An IDLE Stream may have a non-nullptr
    // AudioTrack, which may be recycled for use if the SoundID matches the next Stream playback.
    //
    // PAUSED -> PLAYING through resume()  (see also autoResume())
    // PLAYING -> PAUSED through pause()   (see also autoPause())
    //
    // IDLE is the initial state of a Stream and also when a stream becomes inactive.
    // {PAUSED, PLAYING} -> IDLE through stop() (or if the Sound finishes playing)
    // IDLE -> PLAYING through play().  (there is no way to start a Stream in paused mode).

    ~Stream();
    void setStreamManager(StreamManager* streamManager) { // non-nullptr
        mStreamManager = streamManager; // set in StreamManager constructor, not changed
    }

    // The following methods are monitor locked by mLock.
    //
    // For methods taking a streamID:
    // if the streamID matches the Stream's mStreamID, then method proceeds
    // else the command is ignored with no effect.

    // returns true if the stream needs to be explicitly stopped.
    bool requestStop(int32_t streamID);
    void stop();                    // explicit stop(), typically called from the worker thread.
    void clearAudioTrack();
    void pause(int32_t streamID);
    void autoPause();               // see the Java SoundPool.autoPause documentation for details.
    void resume(int32_t streamID);
    void autoResume();
    void mute(bool muting);
    void dump() const NO_THREAD_SAFETY_ANALYSIS; // disable for ALOGV (see func for details).

    // returns the pair stream if successful, nullptr otherwise
    Stream* playPairStream();

    // These parameters are explicitly checked in the SoundPool class
    // so never deviate from the Java API specified values.
    void setVolume(int32_t streamID, float leftVolume, float rightVolume);
    void setRate(int32_t streamID, float rate);
    void setPriority(int32_t streamID, int priority);
    void setLoop(int32_t streamID, int loop);
    void 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);
    void setStopTimeNs(int64_t stopTimeNs); // systemTime() clock monotonic.

    // The following getters are not locked and have weak consistency.
    // These are considered advisory only - being stale is of nuisance.
    int32_t getPriority() const NO_THREAD_SAFETY_ANALYSIS { return mPriority; }
    int32_t getPairPriority() const NO_THREAD_SAFETY_ANALYSIS {
        return getPairStream()->getPriority();
    }
    int64_t getStopTimeNs() const NO_THREAD_SAFETY_ANALYSIS { return mStopTimeNs; }

    // Can change with setPlay()
    int32_t getStreamID() const NO_THREAD_SAFETY_ANALYSIS { return mStreamID; }

    // Can change with play_l()
    int32_t getSoundID() const NO_THREAD_SAFETY_ANALYSIS { return mSoundID; }

    bool hasSound() const NO_THREAD_SAFETY_ANALYSIS { return mSound.get() != nullptr; }

    // This never changes.  See top of header.
    Stream* getPairStream() const;

private:
    void play_l(const std::shared_ptr<Sound>& sound, int streamID,
            float leftVolume, float rightVolume, int priority, int loop, float rate,
            sp<AudioTrack> releaseTracks[2]) REQUIRES(mLock);
    void stop_l() REQUIRES(mLock);
    void setVolume_l(float leftVolume, float rightVolume) REQUIRES(mLock);

    // For use with AudioTrack callback.
    static void staticCallback(int event, void* user, void* info);
    void callback(int event, void* info, int toggle, int tries)
            NO_THREAD_SAFETY_ANALYSIS; // uses unique_lock

    // StreamManager should be set on construction and not changed.
    // release mLock before calling into StreamManager
    StreamManager*     mStreamManager = nullptr;

    mutable std::mutex  mLock;
    std::atomic_int32_t mStreamID GUARDED_BY(mLock) = 0; // Valid streamIDs are always positive.
    int                 mState GUARDED_BY(mLock) = IDLE;
    std::shared_ptr<Sound> mSound GUARDED_BY(mLock);    // Non-null if playing.
    int32_t             mSoundID GUARDED_BY(mLock) = 0; // SoundID associated with AudioTrack.
    float               mLeftVolume GUARDED_BY(mLock) = 0.f;
    float               mRightVolume GUARDED_BY(mLock) = 0.f;
    int32_t             mPriority GUARDED_BY(mLock) = INT32_MIN;
    int32_t             mLoop GUARDED_BY(mLock) = 0;
    float               mRate GUARDED_BY(mLock) = 0.f;
    bool                mAutoPaused GUARDED_BY(mLock) = false;
    bool                mMuted GUARDED_BY(mLock) = false;

    sp<AudioTrack>      mAudioTrack GUARDED_BY(mLock);
    int                 mToggle GUARDED_BY(mLock) = 0;
    int64_t             mStopTimeNs GUARDED_BY(mLock) = 0;  // if nonzero, time to wait for stop.
};

} // namespace android::soundpool
