/*
 * Copyright (C) 2010 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 "LiveSource"
#include <utils/Log.h>

#include "include/LiveSource.h"
#include "include/M3UParser.h"
#include "include/NuHTTPDataSource.h"

#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/MediaDebug.h>

namespace android {

LiveSource::LiveSource(const char *url)
    : mURL(url),
      mInitCheck(NO_INIT),
      mPlaylistIndex(0),
      mLastFetchTimeUs(-1),
      mSource(new NuHTTPDataSource),
      mSourceSize(0),
      mOffsetBias(0) {
    if (switchToNext()) {
        mInitCheck = OK;
    }
}

LiveSource::~LiveSource() {
}

status_t LiveSource::initCheck() const {
    return mInitCheck;
}

bool LiveSource::loadPlaylist() {
    mPlaylist.clear();
    mPlaylistIndex = 0;

    sp<ABuffer> buffer;
    status_t err = fetchM3U(mURL.c_str(), &buffer);

    if (err != OK) {
        return false;
    }

    mPlaylist = new M3UParser(mURL.c_str(), buffer->data(), buffer->size());

    if (mPlaylist->initCheck() != OK) {
        return false;
    }

    if (!mPlaylist->meta()->findInt32(
                "media-sequence", &mFirstItemSequenceNumber)) {
        mFirstItemSequenceNumber = 0;
    }

    return true;
}

static int64_t getNowUs() {
    struct timeval tv;
    gettimeofday(&tv, NULL);

    return (int64_t)tv.tv_usec + tv.tv_sec * 1000000ll;
}

bool LiveSource::switchToNext() {
    mOffsetBias += mSourceSize;
    mSourceSize = 0;

    if (mLastFetchTimeUs < 0 || getNowUs() >= mLastFetchTimeUs + 15000000ll
        || mPlaylistIndex == mPlaylist->size()) {
        int32_t nextSequenceNumber =
            mPlaylistIndex + mFirstItemSequenceNumber;

        if (!loadPlaylist()) {
            LOGE("failed to reload playlist");
            return false;
        }

        if (mLastFetchTimeUs < 0) {
            mPlaylistIndex = mPlaylist->size() / 2;
        } else {
            if (nextSequenceNumber < mFirstItemSequenceNumber
                    || nextSequenceNumber
                            >= mFirstItemSequenceNumber + (int32_t)mPlaylist->size()) {
                LOGE("Cannot find sequence number %d in new playlist",
                     nextSequenceNumber);

                return false;
            }

            mPlaylistIndex = nextSequenceNumber - mFirstItemSequenceNumber;
        }

        mLastFetchTimeUs = getNowUs();
    }

    AString uri;
    CHECK(mPlaylist->itemAt(mPlaylistIndex, &uri));
    LOGI("switching to %s", uri.c_str());

    if (mSource->connect(uri.c_str()) != OK
            || mSource->getSize(&mSourceSize) != OK) {
        return false;
    }

    mPlaylistIndex++;
    return true;
}

ssize_t LiveSource::readAt(off_t offset, void *data, size_t size) {
    CHECK(offset >= mOffsetBias);
    offset -= mOffsetBias;

    if (offset >= mSourceSize) {
        CHECK_EQ(offset, mSourceSize);

        offset -= mSourceSize;
        if (!switchToNext()) {
            return ERROR_END_OF_STREAM;
        }
    }

    size_t numRead = 0;
    while (numRead < size) {
        ssize_t n = mSource->readAt(
                offset + numRead, (uint8_t *)data + numRead, size - numRead);

        if (n <= 0) {
            break;
        }

        numRead += n;
    }

    return numRead;
}

status_t LiveSource::fetchM3U(const char *url, sp<ABuffer> *out) {
    *out = NULL;

    status_t err = mSource->connect(url);

    if (err != OK) {
        return err;
    }

    off_t size;
    err = mSource->getSize(&size);

    if (err != OK) {
        return err;
    }

    sp<ABuffer> buffer = new ABuffer(size);
    size_t offset = 0;
    while (offset < (size_t)size) {
        ssize_t n = mSource->readAt(
                offset, buffer->data() + offset, size - offset);

        if (n <= 0) {
            return ERROR_IO;
        }

        offset += n;
    }

    *out = buffer;

    return OK;
}

}  // namespace android
