/*
 * Copyright (C) 2012 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 "NBAIO"
//#define LOG_NDEBUG 0

#include <utils/Log.h>
#include <media/nbaio/NBAIO.h>

namespace android {

size_t Format_frameSize(const NBAIO_Format& format)
{
    return format.mFrameSize;
}

const NBAIO_Format Format_Invalid = { 0, 0, AUDIO_FORMAT_INVALID, 0 };

unsigned Format_sampleRate(const NBAIO_Format& format)
{
    if (!Format_isValid(format)) {
        return 0;
    }
    return format.mSampleRate;
}

unsigned Format_channelCount(const NBAIO_Format& format)
{
    if (!Format_isValid(format)) {
        return 0;
    }
    return format.mChannelCount;
}

NBAIO_Format Format_from_SR_C(unsigned sampleRate, unsigned channelCount,
        audio_format_t format)
{
    if (sampleRate == 0 || channelCount == 0 || !audio_is_valid_format(format)) {
        return Format_Invalid;
    }
    NBAIO_Format ret;
    ret.mSampleRate = sampleRate;
    ret.mChannelCount = channelCount;
    ret.mFormat = format;
    ret.mFrameSize = audio_is_linear_pcm(format) ?
            channelCount * audio_bytes_per_sample(format) : sizeof(uint8_t);
    return ret;
}

// This is a default implementation; it is expected that subclasses will optimize this.
ssize_t NBAIO_Sink::writeVia(writeVia_t via, size_t total, void *user, size_t block)
{
    if (!mNegotiated) {
        return (ssize_t) NEGOTIATE;
    }
    static const size_t maxBlock = 32;
    size_t frameSize = Format_frameSize(mFormat);
    ALOG_ASSERT(frameSize > 0 && frameSize <= 8);
    // double guarantees alignment for stack similar to what malloc() gives for heap
    if (block == 0 || block > maxBlock) {
        block = maxBlock;
    }
    double buffer[((frameSize * block) + sizeof(double) - 1) / sizeof(double)];
    size_t accumulator = 0;
    while (accumulator < total) {
        size_t count = total - accumulator;
        if (count > block) {
            count = block;
        }
        ssize_t ret = via(user, buffer, count);
        if (ret > 0) {
            ALOG_ASSERT((size_t) ret <= count);
            size_t maxRet = ret;
            ret = write(buffer, maxRet);
            if (ret > 0) {
                ALOG_ASSERT((size_t) ret <= maxRet);
                accumulator += ret;
                continue;
            }
        }
        return accumulator > 0 ? accumulator : ret;
    }
    return accumulator;
}

// This is a default implementation; it is expected that subclasses will optimize this.
ssize_t NBAIO_Source::readVia(readVia_t via, size_t total, void *user,
                              int64_t readPTS, size_t block)
{
    if (!mNegotiated) {
        return (ssize_t) NEGOTIATE;
    }
    static const size_t maxBlock = 32;
    size_t frameSize = Format_frameSize(mFormat);
    ALOG_ASSERT(frameSize > 0 && frameSize <= 8);
    // double guarantees alignment for stack similar to what malloc() gives for heap
    if (block == 0 || block > maxBlock) {
        block = maxBlock;
    }
    double buffer[((frameSize * block) + sizeof(double) - 1) / sizeof(double)];
    size_t accumulator = 0;
    while (accumulator < total) {
        size_t count = total - accumulator;
        if (count > block) {
            count = block;
        }
        ssize_t ret = read(buffer, count, readPTS);
        if (ret > 0) {
            ALOG_ASSERT((size_t) ret <= count);
            size_t maxRet = ret;
            ret = via(user, buffer, maxRet, readPTS);
            if (ret > 0) {
                ALOG_ASSERT((size_t) ret <= maxRet);
                accumulator += ret;
                continue;
            }
        }
        return accumulator > 0 ? accumulator : ret;
    }
    return accumulator;
}

// Default implementation that only accepts my mFormat
ssize_t NBAIO_Port::negotiate(const NBAIO_Format offers[], size_t numOffers,
                                  NBAIO_Format counterOffers[], size_t& numCounterOffers)
{
    ALOGV("negotiate offers=%p numOffers=%u countersOffers=%p numCounterOffers=%u",
            offers, numOffers, counterOffers, numCounterOffers);
    if (Format_isValid(mFormat)) {
        for (size_t i = 0; i < numOffers; ++i) {
            if (Format_isEqual(offers[i], mFormat)) {
                mNegotiated = true;
                return i;
            }
        }
        if (numCounterOffers > 0) {
            counterOffers[0] = mFormat;
        }
        numCounterOffers = 1;
    } else {
        numCounterOffers = 0;
    }
    return (ssize_t) NEGOTIATE;
}

bool Format_isValid(const NBAIO_Format& format)
{
    return format.mSampleRate != 0 && format.mChannelCount != 0 &&
            format.mFormat != AUDIO_FORMAT_INVALID && format.mFrameSize != 0;
}

bool Format_isEqual(const NBAIO_Format& format1, const NBAIO_Format& format2)
{
    return format1.mSampleRate == format2.mSampleRate &&
            format1.mChannelCount == format2.mChannelCount && format1.mFormat == format2.mFormat &&
            format1.mFrameSize == format2.mFrameSize;
}

}   // namespace android
