/*
 * 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
#define LOG_TAG "SoundPool::SoundDecoder"
#include "utils/Log.h"

#include "SoundDecoder.h"

namespace android::soundpool {

// Maximum Samples that can be background decoded before we block the caller.
static constexpr size_t kMaxQueueSize = 128;

// The amount of time we wait for a new Sound decode request
// before the SoundDecoder thread closes.
static constexpr int32_t kWaitTimeBeforeCloseMs = 1000;

SoundDecoder::SoundDecoder(SoundManager* soundManager, size_t threads)
    : mSoundManager(soundManager)
{
    ALOGV("%s(%p, %zu)", __func__, soundManager, threads);
    // ThreadPool is created, but we don't launch any threads.
    mThreadPool = std::make_unique<ThreadPool>(
            std::min(threads, (size_t)std::thread::hardware_concurrency()),
            "SoundDecoder_");
}

SoundDecoder::~SoundDecoder()
{
    ALOGV("%s()", __func__);
    quit();
}

void SoundDecoder::quit()
{
    ALOGV("%s()", __func__);
    {
        std::lock_guard lock(mLock);
        mQuit = true;
        mQueueSpaceAvailable.notify_all(); // notify all load waiters
        mQueueDataAvailable.notify_all();  // notify all worker threads
    }
    mThreadPool->quit();
}

void SoundDecoder::run(int32_t id __unused /* ALOGV only */)
{
    ALOGV("%s(%d): entering", __func__, id);
    std::unique_lock lock(mLock);
    while (!mQuit) {
        if (mSoundIDs.size() == 0) {
            ALOGV("%s(%d): waiting", __func__, id);
            mQueueDataAvailable.wait_for(
                    lock, std::chrono::duration<int32_t, std::milli>(kWaitTimeBeforeCloseMs));
            if (mSoundIDs.size() == 0) {
                break; // no new sound, exit this thread.
            }
            continue;
        }
        const int32_t soundID = mSoundIDs.front();
        mSoundIDs.pop_front();
        mQueueSpaceAvailable.notify_one();
        ALOGV("%s(%d): processing soundID: %d  size: %zu", __func__, id, soundID, mSoundIDs.size());
        lock.unlock();
        std::shared_ptr<Sound> sound = mSoundManager->findSound(soundID);
        status_t status = NO_INIT;
        if (sound.get() != nullptr) {
            status = sound->doLoad();
        }
        ALOGV("%s(%d): notifying loaded soundID:%d  status:%d", __func__, id, soundID, status);
        mSoundManager->notify(SoundPoolEvent(SoundPoolEvent::SOUND_LOADED, soundID, status));
        lock.lock();
    }
    ALOGV("%s(%d): exiting", __func__, id);
}

void SoundDecoder::loadSound(int32_t soundID)
{
    ALOGV("%s(%d)", __func__, soundID);
    size_t pendingSounds;
    {
        std::unique_lock lock(mLock);
        while (mSoundIDs.size() == kMaxQueueSize) {
            if (mQuit) return;
            ALOGV("%s: waiting soundID: %d size: %zu", __func__, soundID, mSoundIDs.size());
            mQueueSpaceAvailable.wait(lock);
        }
        if (mQuit) return;
        mSoundIDs.push_back(soundID);
        mQueueDataAvailable.notify_one();
        ALOGV("%s: adding soundID: %d  size: %zu", __func__, soundID, mSoundIDs.size());
        pendingSounds = mSoundIDs.size();
    }
    // Launch threads as needed.  The "as needed" is weakly consistent as we release mLock.
    if (pendingSounds > mThreadPool->getActiveThreadCount()) {
        const int32_t id __unused = mThreadPool->launch([this](int32_t id) { run(id); });
        ALOGV_IF(id != 0, "%s: launched thread %d", __func__, id);
    }
}

} // end namespace android::soundpool
