#include <mecha.h>
#include <stdlib.h>

/**
 * Close the network connection underlying this connection, and release resources associated with it.
 *
 * If M_NET_FLAG_FREEPT is set, then free() will be called on the patch table.
 *
 * If M_NET_FLAG_FREEUD is set, then free() will be called on the void* user data.
 */
void mFnet_close(struct mSnet_con *con) {
    con->pt->close(con);

    if ((con->flags & M_NET_FLAG_FREEPT) > 0) {
        free(con->pt);
    }

    if ((con->flags & M_NET_FLAG_FREEUD) > 0) {
        free(con->ud.ud_ptr);
    }
}

/**
 * Set the patch table for the given connection. If should_free is non-zero, then free() will be called on the patch
 * table by mFnet_close().
 */
void mFnet_pt_set(struct mSnet_con *con, struct mSnet_pt *pt, int should_free) {
    con->pt = pt;
    if (should_free > 0) {
        con->flags |= M_NET_FLAG_FREEPT;
    }
}

/**
 * Attempt to write len bytes from buf to the given connection. The number of bytes actually written is written
 * into written_Len, which must be provided.
 *
 * This function is blocking.
 *
 * This function returns MECHA_OK on success, otherwise, MECHA_ERR is returned and the contents of written_len
 * are undefined. On error, whether any bytes were actually sent are undefined.
 */
int mFnet_write(struct mSnet_con *con, const void *buf, size_t len, size_t *wrote_len) {
    return con->pt->write(con, buf, len, wrote_len);
}

/**
 * Attempt to read up to len bytes into buf from the given connection. The number of bytes actually read are written
 * into read_len, which must be provided.
 *
 * This function is blocking.
 *
 * This function returns MECHA_OK on success, otherwise, MECHA_ERR is returned and the contents of read_len are
 * undefined.
 */
int mFnet_read(struct mSnet_con *con, void *buf, size_t len, size_t *read_len) {
    return con->pt->read(con, buf, len, read_len);
}