/*
 * 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.
 */

#include "ARTPSession.h"

#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/foundation/hexdump.h>

#include <ctype.h>
#include <arpa/inet.h>
#include <sys/socket.h>

#include "APacketSource.h"
#include "ARTPConnection.h"
#include "ASessionDescription.h"

namespace android {

ARTPSession::ARTPSession()
    : mInitCheck(NO_INIT) {
}

status_t ARTPSession::setup(const sp<ASessionDescription> &desc) {
    CHECK_EQ(mInitCheck, (status_t)NO_INIT);

    mDesc = desc;

    mRTPConn = new ARTPConnection(
            ARTPConnection::kFakeTimestamps
                | ARTPConnection::kRegularlyRequestFIR);

    looper()->registerHandler(mRTPConn);

    for (size_t i = 1; i < mDesc->countTracks(); ++i) {
        AString connection;
        if (!mDesc->findAttribute(i, "c=", &connection)) {
            // No per-stream connection information, try global fallback.
            if (!mDesc->findAttribute(0, "c=", &connection)) {
                LOG(ERROR) << "Unable to find connection attribtue.";
                return mInitCheck;
            }
        }
        if (!(connection == "IN IP4 127.0.0.1")) {
            LOG(ERROR) << "We only support localhost connections for now.";
            return mInitCheck;
        }

        unsigned port;
        if (!validateMediaFormat(i, &port) || (port & 1) != 0) {
            LOG(ERROR) << "Invalid media format.";
            return mInitCheck;
        }

        sp<APacketSource> source = new APacketSource(mDesc, i);
        if (source->initCheck() != OK) {
            LOG(ERROR) << "Unsupported format.";
            return mInitCheck;
        }

        int rtpSocket = MakeUDPSocket(port);
        int rtcpSocket = MakeUDPSocket(port + 1);

        mTracks.push(TrackInfo());
        TrackInfo *info = &mTracks.editItemAt(mTracks.size() - 1);
        info->mRTPSocket = rtpSocket;
        info->mRTCPSocket = rtcpSocket;

        sp<AMessage> notify = new AMessage(kWhatAccessUnitComplete, id());
        notify->setSize("track-index", mTracks.size() - 1);

        mRTPConn->addStream(
                rtpSocket, rtcpSocket, mDesc, i, notify, false /* injected */);

        info->mPacketSource = source;
    }

    mInitCheck = OK;

    return OK;
}

// static
int ARTPSession::MakeUDPSocket(unsigned port) {
    int s = socket(AF_INET, SOCK_DGRAM, 0);
    CHECK_GE(s, 0);

    struct sockaddr_in addr;
    memset(addr.sin_zero, 0, sizeof(addr.sin_zero));
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = INADDR_ANY;
    addr.sin_port = htons(port);

    CHECK_EQ(0, bind(s, (const struct sockaddr *)&addr, sizeof(addr)));

    return s;
}

ARTPSession::~ARTPSession() {
    for (size_t i = 0; i < mTracks.size(); ++i) {
        TrackInfo *info = &mTracks.editItemAt(i);

        info->mPacketSource->signalEOS(UNKNOWN_ERROR);

        close(info->mRTPSocket);
        close(info->mRTCPSocket);
    }
}

void ARTPSession::onMessageReceived(const sp<AMessage> &msg) {
    switch (msg->what()) {
        case kWhatAccessUnitComplete:
        {
            int32_t firstRTCP;
            if (msg->findInt32("first-rtcp", &firstRTCP)) {
                // There won't be an access unit here, it's just a notification
                // that the data communication worked since we got the first
                // rtcp packet.
                break;
            }

            size_t trackIndex;
            CHECK(msg->findSize("track-index", &trackIndex));

            int32_t eos;
            if (msg->findInt32("eos", &eos) && eos) {
                TrackInfo *info = &mTracks.editItemAt(trackIndex);
                info->mPacketSource->signalEOS(ERROR_END_OF_STREAM);
                break;
            }

            sp<RefBase> obj;
            CHECK(msg->findObject("access-unit", &obj));

            sp<ABuffer> accessUnit = static_cast<ABuffer *>(obj.get());

            uint64_t ntpTime;
            CHECK(accessUnit->meta()->findInt64(
                        "ntp-time", (int64_t *)&ntpTime));

#if 0
#if 0
            printf("access unit complete size=%d\tntp-time=0x%016llx\n",
                   accessUnit->size(), ntpTime);
#else
            LOG(INFO) << "access unit complete, "
                      << "size=" << accessUnit->size() << ", "
                      << "ntp-time=" << ntpTime;
            hexdump(accessUnit->data(), accessUnit->size());
#endif
#endif

#if 0
            CHECK_GE(accessUnit->size(), 5u);
            CHECK(!memcmp("\x00\x00\x00\x01", accessUnit->data(), 4));
            unsigned x = accessUnit->data()[4];

            LOG(INFO) << "access unit complete: "
                      << StringPrintf("nalType=0x%02x, nalRefIdc=0x%02x",
                                      x & 0x1f, (x & 0x60) >> 5);
#endif

            accessUnit->meta()->setInt64("ntp-time", ntpTime);
            accessUnit->meta()->setInt64("timeUs", 0);

#if 0
            int32_t damaged;
            if (accessUnit->meta()->findInt32("damaged", &damaged)
                    && damaged != 0) {
                LOG(INFO) << "ignoring damaged AU";
            } else
#endif
            {
                TrackInfo *info = &mTracks.editItemAt(trackIndex);
                info->mPacketSource->queueAccessUnit(accessUnit);
            }
            break;
        }

        default:
            TRESPASS();
            break;
    }
}

bool ARTPSession::validateMediaFormat(size_t index, unsigned *port) const {
    AString format;
    mDesc->getFormat(index, &format);

    ssize_t i = format.find(" ");
    if (i < 0) {
        return false;
    }

    ++i;
    size_t j = i;
    while (isdigit(format.c_str()[j])) {
        ++j;
    }
    if (format.c_str()[j] != ' ') {
        return false;
    }

    AString portString(format, i, j - i);

    char *end;
    unsigned long x = strtoul(portString.c_str(), &end, 10);
    if (end == portString.c_str() || *end != '\0') {
        return false;
    }

    if (x == 0 || x > 65535) {
        return false;
    }

    *port = x;

    return true;
}

size_t ARTPSession::countTracks() {
    return mTracks.size();
}

sp<MediaSource> ARTPSession::trackAt(size_t index) {
    CHECK_LT(index, mTracks.size());
    return mTracks.editItemAt(index).mPacketSource;
}

}  // namespace android
