/*
 * 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_NDEBUG 0
#define LOG_TAG "UDPPusher"
#include <utils/Log.h>

#include "UDPPusher.h"

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

#include <sys/socket.h>

namespace android {

UDPPusher::UDPPusher(const char *filename, unsigned port)
    : mFile(fopen(filename, "rb")),
      mFirstTimeMs(0),
      mFirstTimeUs(0) {
    CHECK(mFile != NULL);

    mSocket = socket(AF_INET, SOCK_DGRAM, 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 = 0;

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

    memset(mRemoteAddr.sin_zero, 0, sizeof(mRemoteAddr.sin_zero));
    mRemoteAddr.sin_family = AF_INET;
    mRemoteAddr.sin_addr.s_addr = INADDR_ANY;
    mRemoteAddr.sin_port = htons(port);
}

UDPPusher::~UDPPusher() {
    close(mSocket);
    mSocket = -1;

    fclose(mFile);
    mFile = NULL;
}

void UDPPusher::start() {
    uint32_t timeMs;
    CHECK_EQ(fread(&timeMs, 1, sizeof(timeMs), mFile), sizeof(timeMs));
    mFirstTimeMs = fromlel(timeMs);
    mFirstTimeUs = ALooper::GetNowUs();

    (new AMessage(kWhatPush, this))->post();
}

bool UDPPusher::onPush() {
    uint32_t length;
    if (fread(&length, 1, sizeof(length), mFile) < sizeof(length)) {
        ALOGI("No more data to push.");
        return false;
    }

    length = fromlel(length);

    CHECK_GT(length, 0u);

    sp<ABuffer> buffer = new ABuffer(length);
    if (fread(buffer->data(), 1, length, mFile) < length) {
        ALOGE("File truncated?.");
        return false;
    }

    ssize_t n = sendto(
            mSocket, buffer->data(), buffer->size(), 0,
            (const struct sockaddr *)&mRemoteAddr, sizeof(mRemoteAddr));

    CHECK_EQ(n, (ssize_t)buffer->size());

    uint32_t timeMs;
    if (fread(&timeMs, 1, sizeof(timeMs), mFile) < sizeof(timeMs)) {
        ALOGI("No more data to push.");
        return false;
    }

    timeMs = fromlel(timeMs);
    CHECK_GE(timeMs, mFirstTimeMs);

    timeMs -= mFirstTimeMs;
    int64_t whenUs = mFirstTimeUs + timeMs * 1000ll;
    int64_t nowUs = ALooper::GetNowUs();
    (new AMessage(kWhatPush, this))->post(whenUs - nowUs);

    return true;
}

void UDPPusher::onMessageReceived(const sp<AMessage> &msg) {
    switch (msg->what()) {
        case kWhatPush:
        {
            if (!onPush() && !(ntohs(mRemoteAddr.sin_port) & 1)) {
                ALOGI("emulating BYE packet");

                sp<ABuffer> buffer = new ABuffer(8);
                uint8_t *data = buffer->data();
                *data++ = (2 << 6) | 1;
                *data++ = 203;
                *data++ = 0;
                *data++ = 1;
                *data++ = 0x8f;
                *data++ = 0x49;
                *data++ = 0xc0;
                *data++ = 0xd0;
                buffer->setRange(0, 8);

                struct sockaddr_in tmp = mRemoteAddr;
                tmp.sin_port = htons(ntohs(mRemoteAddr.sin_port) | 1);

                ssize_t n = sendto(
                        mSocket, buffer->data(), buffer->size(), 0,
                        (const struct sockaddr *)&tmp,
                        sizeof(tmp));

                CHECK_EQ(n, (ssize_t)buffer->size());
            }
            break;
        }

        default:
            TRESPASS();
            break;
    }
}

}  // namespace android

