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

    // 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 { return mPriority; }
    int32_t getPairPriority() const { return getPairStream()->getPriority(); }
    int64_t getStopTimeNs() const { return mStopTimeNs; }

    int32_t getStreamID() const { return mStreamID; }  // Can change with setPlay()
    int32_t getSoundID() const { return mSoundID; }    // Can change with play_l()
    bool hasSound() const { return mSound.get() != nullptr; }

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

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]);
    void stop_l();
    void setVolume_l(float leftVolume, float rightVolume);

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

    // 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 = 0;          // Note: valid streamIDs are always positive.
    int                 mState = IDLE;
    std::shared_ptr<Sound> mSound;              // Non-null if playing.
    int32_t             mSoundID = 0;           // The sound ID associated with the AudioTrack.
    float               mLeftVolume = 0.f;
    float               mRightVolume = 0.f;
    int32_t             mPriority = INT32_MIN;
    int32_t             mLoop = 0;
    float               mRate = 0.f;
    bool                mAutoPaused = false;
    bool                mMuted = false;

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

} // namespace android::soundpool
