/*
 * Copyright 2018 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include <stdlib.h>
#include "l2cap.h"
#include "sendQ.h"
#include "log.h"
#include "mt.h"

struct packet {
     struct packet *next;
     l2c_handle_t   conn;
     sg             s;
};

struct sendQ {
    pthread_mutex_t lock;
    uniq_t          l2cNotifH;

    struct packet  *head;
    struct packet  *tail;
    uint32_t        maxMsgsPerConn;
};



/*
 * FUNCTION: sendQueueTryTx
 * USE:      Try to send for ther queue
 * PARAMS:   the q - the SendQ object
 * RETURN:   NONE
 * NOTES:    call with q->lock taken
 */
static void sendQueueTryTx(struct sendQ *q)
{
    struct packet *t;
    uint8_t ret;

    while (q->head) {

        /* try a send */
        ret = l2cApiDataTx(q->head->conn, q->head->s);
        switch(ret) {
        case L2C_TX_ACCEPTED:
            /* nothing to do here */
            break;
        case L2C_TX_ERROR:
            logw("L2C TX fail on "HANDLEFMT"\n", HANDLECNV(q->head->conn));
        case L2C_TX_NO_CONN:
            sgFree(q->head->s);
            break;
        case L2C_TX_TRY_LATER:
            return;
        }

        if (q->tail == q->head) {
            free(q->head);
            q->tail = NULL;
            q->head = NULL;
        } else {
            t = q->head;
            q->head = q->head->next;
            free(t);
        }
    }
}

/*
 * FUNCTION: sendQueueL2cBufNotif
 * USE:      Called by L2C when a TX buffer potentially opens up
 * PARAMS:   cbkData - for us this is the sendQ
 *           notifData - unused for L2C send notifications
 *           handle - handle of our notification handler. unused.
 * RETURN:   NONE
 * NOTES:
 */
static void sendQueueL2cBufNotif(void *cbkData, const void *notifData, uniq_t handle)
{
    struct sendQ *q = (struct sendQ*)cbkData;

    if (pthread_mutex_trylock(&q->lock))
        return;
    sendQueueTryTx(q);
    pthread_mutex_unlock(&q->lock);
}

/*
 * FUNCTION: sendQueueAlloc
 * USE:      Create a sendQ
 * PARAMS:   maxMsgsPerConn - max messages to allow per connection
 * RETURN:   the SendQ object or NULL on error
 * NOTES:
 */
struct sendQ* sendQueueAlloc(uint32_t maxMsgsPerConn)
{
    struct sendQ *q = (struct sendQ*)calloc(1, sizeof(struct sendQ));

    if (!q)
        goto fail_oom;

    q->maxMsgsPerConn = maxMsgsPerConn;

    if (pthread_mutex_init(&q->lock, NULL))
        goto fail_mutex;

    q->l2cNotifH = l2cApiRegisterWriteBufNotif(sendQueueL2cBufNotif, q);
    if (!q->l2cNotifH)
        goto fail_notif_reg;

    return q;


fail_notif_reg:
    pthread_mutex_destroy(&q->lock);

fail_mutex:
    free(q);

fail_oom:
    return NULL;
}

/*
 * FUNCTION: sendQueueFree
 * USE:      Free a sendQ
 * PARAMS:   q - the SendQ
 * RETURN:   NONE
 * NOTES:    The free itself is async and will complete at a later time
 */
void sendQueueFree(struct sendQ *q)
{
    struct packet *p;

    pthread_mutex_lock(&q->lock);
    l2cApiUnegisterWriteBufNotif(q->l2cNotifH);
    while (q->head) {
        p = q->head;
        q->head = q->head->next;
        sgFree(p->s);
        free(p);
    }
    pthread_mutex_unlock(&q->lock);
    pthread_mutex_destroy(&q->lock);
    free(q);
}

/*
 * FUNCTION: sendQueueTxInt
 * USE:      Enqueue a packet to send using the sendQ, enforce quotas if needed
 * PARAMS:   q - the SendQ
 *           conn - the L2C connection
 *           s - the SG to send
 *           enforceQuotas - true to enforce quotas, false else
 * RETURN:   false on error
 * NOTES:
 */
static bool sendQueueTxInt(struct sendQ *q, l2c_handle_t conn, sg s, bool enforceQuotas)
{
    uint32_t msgsForConnAlready = 0;
    struct packet *t;
    bool ret = false;

    pthread_mutex_lock(&q->lock);

    for (t = q->head; t; t = t->next)
        if (t->conn == conn)
            msgsForConnAlready++;

    if (!enforceQuotas || msgsForConnAlready < q->maxMsgsPerConn) {
        t = (struct packet*)calloc(1, sizeof(struct packet));
        if (t) {

            t->conn = conn;
            t->s = s;
            if (q->tail)
                q->tail->next = t;
            else
                q->head = t;
            q->tail = t;

            ret = true;
        }
    }

    sendQueueTryTx(q);
    pthread_mutex_unlock(&q->lock);
    return ret;
}

/*
 * FUNCTION: sendQueueForceTx
 * USE:      Enqueue a packet to send using the sendQ, ignore quotas
 * PARAMS:   q - the SendQ
 *           conn - the L2C connection
 *           s - the SG to send
 * RETURN:   false on error
 * NOTES:
 */
bool sendQueueForceTx(struct sendQ *q, l2c_handle_t conn, sg s)
{
    return sendQueueTxInt(q, conn, s, false);
}

/*
 * FUNCTION: sendQueueTx
 * USE:      Enqueue a packet to send using the sendQ
 * PARAMS:   q - the SendQ
 *           conn - the L2C connection
 *           s - the SG to send
 * RETURN:   false on error of over limit
 * NOTES:
 */
bool sendQueueTx(struct sendQ *q, l2c_handle_t conn, sg s)
{
    return sendQueueTxInt(q, conn, s, true);
}

/*
 * FUNCTION: sendQueueCanTx
 * USE:      Says if a packet may be queneued at this point
 * PARAMS:   q - the SendQ
 *           conn - the L2C connection
 * RETURN:   true if so, false else
 * NOTES:    Note that the reply is stale even by the time it is received and should be use just as a hint
 */
bool sendQueueCanTx(struct sendQ *q, l2c_handle_t conn)
{
    uint32_t msgsForConnAlready = 0;
    struct packet *t;
    bool ret;

    pthread_mutex_lock(&q->lock);

    for (t = q->head; t; t = t->next)
        if (t->conn == conn)
            msgsForConnAlready++;

    ret = msgsForConnAlready < q->maxMsgsPerConn;

    sendQueueTryTx(q);
    pthread_mutex_unlock(&q->lock);

    return ret;
}

/*
 * FUNCTION: sendQueueDelPackets
 * USE:      Delete all queued packets to a given connection
 * PARAMS:   q - the SendQ
 *           conn - the L2C connection whose packets we want to kill
 * RETURN:   NONE
 * NOTES:
 */
void sendQueueDelPackets(struct sendQ *q, l2c_handle_t conn)
{
    struct packet *t, *p = NULL;

    pthread_mutex_lock(&q->lock);

    t = q->head;
    while (t) {
        if (t->conn == conn) {

            sgFree(t->s);

            if (q->tail == t)
                q->tail = p;

            if (p) {
                p->next = t->next;
                free(t);
                t = p->next;
            } else {
                q->head = t->next;
                free(t);
                t = q->head;
            }

        } else {
            p = t;
            t = t->next;
        }
    }

    sendQueueTryTx(q);
    pthread_mutex_unlock(&q->lock);
}

