/*
 * Copyright (C) 2011 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.
 */

#ifndef __AAH_TX_SENDER_H__
#define __AAH_TX_SENDER_H__

#include <media/stagefright/foundation/ALooper.h>
#include <media/stagefright/foundation/AHandlerReflector.h>
#include <utils/RefBase.h>
#include <utils/threads.h>

#include "aah_tx_packet.h"
#include "pipe_event.h"

namespace android {

template <typename T> class CircularBuffer {
  public:
    CircularBuffer(size_t capacity);
    ~CircularBuffer();
    void push_back(const T& item);;
    void pop_front();
    size_t size() const;
    bool isFull() const;
    bool isEmpty() const;
    const T& itemAt(size_t index) const;
    const T& operator[](size_t index) const;

  private:
    T* mBuffer;
    size_t mCapacity;
    size_t mHead;
    size_t mTail;
    size_t mFillCount;

    DISALLOW_EVIL_CONSTRUCTORS(CircularBuffer);
};

class AAH_TXSender : public virtual RefBase {
  public:
    ~AAH_TXSender();

    static sp<AAH_TXSender> GetInstance();

    ALooper::handler_id handlerID() { return mReflector->id(); }

    // an IP address and port
    struct Endpoint {
        Endpoint();
        Endpoint(uint32_t a, uint16_t p);
        bool operator<(const Endpoint& other) const;

        uint32_t addr;
        uint16_t port;
    };

    uint16_t registerEndpoint(const Endpoint& endpoint);
    void unregisterEndpoint(const Endpoint& endpoint);

    enum {
        kWhatSendPacket,
        kWhatTrimRetryBuffers,
        kWhatSendHeartbeats,
    };

    // fields for SendPacket messages
    static const char* kSendPacketIPAddr;
    static const char* kSendPacketPort;
    static const char* kSendPacketTRTPPacket;

  private:
    AAH_TXSender();

    static Mutex sLock;
    static wp<AAH_TXSender> sInstance;
    static uint32_t sNextEpoch;
    static bool sNextEpochValid;

    static uint32_t getNextEpoch();

    typedef CircularBuffer<sp<TRTPPacket> > RetryBuffer;

    // state maintained on a per-endpoint basis
    struct EndpointState {
        EndpointState(uint32_t epoch);
        RetryBuffer retry;
        int playerRefCount;
        uint16_t trtpSeqNumber;
        uint16_t nextProgramID;
        uint32_t epoch;
    };

    friend class AHandlerReflector<AAH_TXSender>;
    void onMessageReceived(const sp<AMessage>& msg);
    void onSendPacket(const sp<AMessage>& msg);
    void doSendPacket_l(const sp<TRTPPacket>& packet,
                        const Endpoint& endpoint);
    void trimRetryBuffers();
    void sendHeartbeats();
    bool shouldSendHeartbeats_l();

    sp<ALooper> mLooper;
    sp<AHandlerReflector<AAH_TXSender> > mReflector;

    int mSocket;
    nsecs_t mLastSentPacketTime;

    DefaultKeyedVector<Endpoint, EndpointState*> mEndpointMap;
    Mutex mEndpointLock;

    static const int kRetryTrimIntervalUs;
    static const int kHeartbeatIntervalUs;
    static const int kRetryBufferCapacity;
    static const nsecs_t kHeartbeatTimeout;

    class RetryReceiver : public Thread {
      private:
        friend class AAH_TXSender;

        RetryReceiver(AAH_TXSender* sender);
        virtual ~RetryReceiver();
        virtual bool threadLoop();
        void handleRetryRequest();

        static const int kMaxReceiverPacketLen;
        static const uint32_t kRetryRequestID;
        static const uint32_t kFastStartRequestID;
        static const uint32_t kRetryNakID;

        AAH_TXSender* mSender;
        PipeEvent mWakeupEvent;
    };

    sp<RetryReceiver> mRetryReceiver;

    DISALLOW_EVIL_CONSTRUCTORS(AAH_TXSender);
};

struct RetryPacket {
    uint32_t id;
    uint32_t endpointIP;
    uint16_t endpointPort;
    uint16_t seqStart;
    uint16_t seqEnd;
} __attribute__((packed));

}  // namespace android

#endif  // __AAH_TX_SENDER_H__
