/*
 * Copyright (C) 2016 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_TAG "AAudioStreamTracker"
//#define LOG_NDEBUG 0
#include <utils/Log.h>

#include <iomanip>
#include <iostream>
#include <sstream>

#include <aaudio/AAudio.h>
#include <utils/String16.h>

#include "AAudioStreamTracker.h"

using namespace android;
using namespace aaudio;

int32_t AAudioStreamTracker::removeStreamByHandle(
        aaudio_handle_t streamHandle) {
    std::lock_guard<std::mutex> lock(mHandleLock);
    auto count = mStreamsByHandle.erase(streamHandle);
    return static_cast<int32_t>(count);
}

sp<AAudioServiceStreamBase> AAudioStreamTracker::getStreamByHandle(
        aaudio_handle_t streamHandle) {
    std::lock_guard<std::mutex> lock(mHandleLock);
    sp<AAudioServiceStreamBase> serviceStream;
    auto it = mStreamsByHandle.find(streamHandle);
    if (it != mStreamsByHandle.end()) {
        serviceStream = it->second;
    }
    return serviceStream;
}

// The port handle is only available when the stream is started.
// So we have to iterate over all the streams.
// Luckily this rarely happens.
sp<AAudioServiceStreamBase> AAudioStreamTracker::findStreamByPortHandle(
        audio_port_handle_t portHandle) {
    std::lock_guard<std::mutex> lock(mHandleLock);
    sp<AAudioServiceStreamBase> serviceStream;
    auto it = mStreamsByHandle.begin();
    while (it != mStreamsByHandle.end()) {
        auto candidate = it->second;
        if (candidate->getPortHandle() == portHandle) {
            serviceStream = candidate;
            break;
        }
        it++;
    }
    return serviceStream;
}

// advance to next legal handle value
__attribute__((no_sanitize("integer")))
aaudio_handle_t AAudioStreamTracker::bumpHandle(aaudio_handle_t handle) {
    handle++;
    // Only use positive integers.
    if (handle <= 0) {
        handle = 1;
    }
    return handle;
}

aaudio_handle_t AAudioStreamTracker::addStreamForHandle(
        const sp<AAudioServiceStreamBase>& serviceStream) {
    std::lock_guard<std::mutex> lock(mHandleLock);
    aaudio_handle_t handle = mPreviousHandle;
    // Assign a unique handle.
    while (true) {
        handle = bumpHandle(handle);
        sp<AAudioServiceStreamBase> oldServiceStream = mStreamsByHandle[handle];
        // Is this an unused handle? It would be extremely unlikely to wrap
        // around and collide with a very old handle. But just in case.
        if (oldServiceStream.get() == nullptr) {
            mStreamsByHandle[handle] = serviceStream;
            break;
        }
    }
    mPreviousHandle = handle;
    return handle;
}

std::string AAudioStreamTracker::dump() const NO_THREAD_SAFETY_ANALYSIS {
    std::stringstream result;
    const bool isLocked = AAudio_tryUntilTrue(
            [this]()->bool { return mHandleLock.try_lock(); } /* f */,
            50 /* times */,
            20 /* sleepMs */);
    if (!isLocked) {
        result << "AAudioStreamTracker may be deadlocked\n";
    } else {
        result << "Stream Handles:\n";
        for (const auto&  it : mStreamsByHandle) {
            aaudio_handle_t handle = it.second->getHandle();
            result << "    0x" << std::setfill('0') << std::setw(8) << std::hex << handle
                   << std::dec << std::setfill(' ') << "\n";
        }

        mHandleLock.unlock();
    }
    return result.str();
}
