/*
 * 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 "TimedTextSRTSource_test"
#include <utils/Log.h>

#include <gtest/gtest.h>

#include <binder/Parcel.h>
#include <media/stagefright/foundation/AString.h>
#include <media/stagefright/DataSource.h>
#include <media/stagefright/MediaErrors.h>
#include <utils/misc.h>

#include <TimedTextSource.h>
#include <TimedTextSRTSource.h>

namespace android {
namespace test {

static const int kSecToUsec = 1000000;
static const int kSecToMsec = 1000;
static const int kMsecToUsec = 1000;

/* SRT format (http://en.wikipedia.org/wiki/SubRip)
 *   Subtitle number
 *   Start time --> End time
 *   Text of subtitle (one or more lines)
 *   Blank lines
 */
static const char *kSRTString =
    "1\n00:00:1,000 --> 00:00:1,500\n1\n\n"
    "2\n00:00:2,000 --> 00:00:2,500\n2\n\n"
    "3\n00:00:3,000 --> 00:00:3,500\n3\n\n"
    "4\n00:00:4,000 --> 00:00:4,500\n4\n\n"
    "5\n00:00:5,000 --> 00:00:5,500\n5\n\n"
    // edge case : previos end time = next start time
    "6\n00:00:5,500 --> 00:00:5,800\n6\n\n"
    "7\n00:00:5,800 --> 00:00:6,000\n7\n\n"
    "8\n00:00:6,000 --> 00:00:7,000\n8\n\n";

class SRTDataSourceStub : public DataSource {
public:
    SRTDataSourceStub(const char *data, size_t size) :
        mData(data), mSize(size) {}
    virtual ~SRTDataSourceStub() {}

    virtual status_t initCheck() const {
        return OK;
    }

    virtual ssize_t readAt(off64_t offset, void *data, size_t size) {
        if ((size_t)offset >= mSize) return 0;

        ssize_t avail = mSize - offset;
        if ((size_t)avail > size) {
            avail = size;
        }
        memcpy(data, mData + offset, avail);
        return avail;
    }

private:
    const char *mData;
    size_t mSize;
};

class TimedTextSRTSourceTest : public testing::Test {
protected:
    void SetUp() {
        sp<DataSource> stub= new SRTDataSourceStub(
                kSRTString,
                strlen(kSRTString));
        mSource = new TimedTextSRTSource(stub);
        mSource->start();
    }

    void CheckStartTimeMs(const Parcel& parcel, int32_t timeMs) {
        int32_t intval;
        parcel.setDataPosition(8);
        parcel.readInt32(&intval);
        EXPECT_EQ(timeMs, intval);
    }

    void CheckDataEquals(const Parcel& parcel, const char* content) {
        int32_t intval;
        parcel.setDataPosition(16);
        parcel.readInt32(&intval);
        parcel.setDataPosition(24);
        const char* data = (const char*) parcel.readInplace(intval);

        int32_t content_len = strlen(content);
        EXPECT_EQ(content_len, intval);
        EXPECT_TRUE(strncmp(data, content, content_len) == 0);
    }

    sp<TimedTextSource> mSource;
    int64_t startTimeUs;
    int64_t endTimeUs;
    Parcel parcel;
    AString subtitle;
    status_t err;
};

TEST_F(TimedTextSRTSourceTest, readAll) {
    for (int i = 1; i <= 5; i++) {
        err = mSource->read(&startTimeUs, &endTimeUs, &parcel);
        EXPECT_EQ(OK, err);
        CheckStartTimeMs(parcel, i * kSecToMsec);
        subtitle = AStringPrintf("%d\n\n", i);
        CheckDataEquals(parcel, subtitle.c_str());
    }
    // read edge cases
    err = mSource->read(&startTimeUs, &endTimeUs, &parcel);
    EXPECT_EQ(OK, err);
    CheckStartTimeMs(parcel, 5500);
    subtitle = AStringPrintf("6\n\n");
    CheckDataEquals(parcel, subtitle.c_str());

    err = mSource->read(&startTimeUs, &endTimeUs, &parcel);
    EXPECT_EQ(OK, err);
    CheckStartTimeMs(parcel, 5800);
    subtitle = AStringPrintf("7\n\n");
    CheckDataEquals(parcel, subtitle.c_str());

    err = mSource->read(&startTimeUs, &endTimeUs, &parcel);
    EXPECT_EQ(OK, err);
    CheckStartTimeMs(parcel, 6000);
    subtitle = AStringPrintf("8\n\n");
    CheckDataEquals(parcel, subtitle.c_str());

    err = mSource->read(&startTimeUs, &endTimeUs, &parcel);
    EXPECT_EQ(ERROR_END_OF_STREAM, err);
}

TEST_F(TimedTextSRTSourceTest, seekTimeIsEarlierThanFirst) {
    MediaSource::ReadOptions options;
    options.setSeekTo(500, MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC);
    err = mSource->read(&startTimeUs, &endTimeUs, &parcel, &options);
    EXPECT_EQ(OK, err);
    EXPECT_EQ(1 * kSecToUsec, startTimeUs);
    CheckStartTimeMs(parcel, 1 * kSecToMsec);
}

TEST_F(TimedTextSRTSourceTest, seekTimeIsLaterThanLast) {
    MediaSource::ReadOptions options;
    options.setSeekTo(7 * kSecToUsec, MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC);
    err = mSource->read(&startTimeUs, &endTimeUs, &parcel, &options);
    EXPECT_EQ(ERROR_END_OF_STREAM, err);

    options.setSeekTo(8 * kSecToUsec, MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC);
    err = mSource->read(&startTimeUs, &endTimeUs, &parcel, &options);
    EXPECT_EQ(ERROR_END_OF_STREAM, err);
}

TEST_F(TimedTextSRTSourceTest, seekTimeIsMatched) {
    for (int i = 1; i <= 5; i++) {
        MediaSource::ReadOptions options;
        options.setSeekTo(i * kSecToUsec, MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC);
        err = mSource->read(&startTimeUs, &endTimeUs, &parcel, &options);
        EXPECT_EQ(OK, err);
        EXPECT_EQ(i * kSecToUsec, startTimeUs);

        options.setSeekTo(i * kSecToUsec + 100, MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC);
        err = mSource->read(&startTimeUs, &endTimeUs, &parcel, &options);
        EXPECT_EQ(OK, err);
        EXPECT_EQ(i * kSecToUsec, startTimeUs);
    }
}

TEST_F(TimedTextSRTSourceTest, seekTimeInBetweenTwo) {
    for (int i = 1; i <= 4; i++) {
        MediaSource::ReadOptions options;
        options.setSeekTo(i * kSecToUsec + 500000, MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC);
        err = mSource->read(&startTimeUs, &endTimeUs, &parcel, &options);
        EXPECT_EQ(OK, err);
        EXPECT_EQ((i + 1) * kSecToUsec, startTimeUs);

        options.setSeekTo(i * kSecToUsec + 600000, MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC);
        err = mSource->read(&startTimeUs, &endTimeUs, &parcel, &options);
        EXPECT_EQ(OK, err);
        EXPECT_EQ((i + 1) * kSecToUsec, startTimeUs);
    }
}

TEST_F(TimedTextSRTSourceTest, checkEdgeCase) {
    MediaSource::ReadOptions options;
    options.setSeekTo(5500 * kMsecToUsec, MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC);
    err = mSource->read(&startTimeUs, &endTimeUs, &parcel, &options);
    EXPECT_EQ(OK, err);
    EXPECT_EQ(5500 * kMsecToUsec, startTimeUs);
    subtitle = AStringPrintf("6\n\n");
    CheckDataEquals(parcel, subtitle.c_str());

    options.setSeekTo(5800 * kMsecToUsec, MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC);
    err = mSource->read(&startTimeUs, &endTimeUs, &parcel, &options);
    EXPECT_EQ(OK, err);
    EXPECT_EQ(5800 * kMsecToUsec, startTimeUs);
    subtitle = AStringPrintf("7\n\n");
    CheckDataEquals(parcel, subtitle.c_str());

    options.setSeekTo(6000 * kMsecToUsec, MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC);
    err = mSource->read(&startTimeUs, &endTimeUs, &parcel, &options);
    EXPECT_EQ(OK, err);
    EXPECT_EQ(6000 * kMsecToUsec, startTimeUs);
    subtitle = AStringPrintf("8\n\n");
    CheckDataEquals(parcel, subtitle.c_str());
}

}  // namespace test
}  // namespace android
