/*
 * Copyright (c) 2008-2010 Wayne Meissner
 * Copyright (C) 2009 Aman Gupta <aman@tmm1.net>
 * 
 * Copyright (c) 2008-2013, Ruby FFI project contributors
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the Ruby FFI project nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef _MSC_VER
# include <stdint.h>
# include <stdbool.h>
#else
# include "win32/stdbool.h"
# include "win32/stdint.h"
#endif
#include <limits.h>
#include <ruby.h>
#include "rbffi.h"
#include "rbffi_endian.h"
#include "AbstractMemory.h"

#define BUFFER_EMBED_MAXLEN (8)
typedef struct Buffer {
    AbstractMemory memory;
    
    union {
        VALUE rbParent; /* link to parent buffer */
        char* storage; /* start of malloc area */
        long embed[BUFFER_EMBED_MAXLEN / sizeof(long)]; /* storage for tiny allocations */
    } data;
} Buffer;

static VALUE buffer_allocate(VALUE klass);
static VALUE buffer_initialize(int argc, VALUE* argv, VALUE self);
static void buffer_release(Buffer* ptr);
static void buffer_mark(Buffer* ptr);
static VALUE buffer_free(VALUE self);

static VALUE BufferClass = Qnil;

static VALUE
buffer_allocate(VALUE klass)
{
    Buffer* buffer;
    VALUE obj;

    obj = Data_Make_Struct(klass, Buffer, NULL, buffer_release, buffer);
    buffer->data.rbParent = Qnil;
    buffer->memory.flags = MEM_RD | MEM_WR;

    return obj;
}

static void
buffer_release(Buffer* ptr)
{
    if ((ptr->memory.flags & MEM_EMBED) == 0 && ptr->data.storage != NULL) {
        xfree(ptr->data.storage);
        ptr->data.storage = NULL;
    }
    
    xfree(ptr);
}

/*
 * call-seq: initialize(size, count=1, clear=false)
 * @param [Integer, Symbol, #size] Type or size in bytes of a buffer cell
 * @param [Fixnum] count number of cell in the Buffer
 * @param [Boolean] clear if true, set the buffer to all-zero
 * @return [self]
 * @raise {NoMemoryError} if failed to allocate memory for Buffer
 * A new instance of Buffer.
 */
static VALUE
buffer_initialize(int argc, VALUE* argv, VALUE self)
{
    VALUE rbSize = Qnil, rbCount = Qnil, rbClear = Qnil;
    Buffer* p;
    int nargs;

    Data_Get_Struct(self, Buffer, p);

    nargs = rb_scan_args(argc, argv, "12", &rbSize, &rbCount, &rbClear);
    p->memory.typeSize = rbffi_type_size(rbSize);
    p->memory.size = p->memory.typeSize * (nargs > 1 ? NUM2LONG(rbCount) : 1);

    if (p->memory.size > BUFFER_EMBED_MAXLEN) {
        p->data.storage = xmalloc(p->memory.size + 7);
        if (p->data.storage == NULL) {
            rb_raise(rb_eNoMemError, "Failed to allocate memory size=%lu bytes", p->memory.size);
            return Qnil;
        }

        /* ensure the memory is aligned on at least a 8 byte boundary */
        p->memory.address = (void *) (((uintptr_t) p->data.storage + 0x7) & (uintptr_t) ~0x7UL);
    
        if (p->memory.size > 0 && (nargs < 3 || RTEST(rbClear))) {
            memset(p->memory.address, 0, p->memory.size);
        }
    
    } else {
        p->memory.flags |= MEM_EMBED;
        p->memory.address = (void *) &p->data.embed[0];
    }

    if (rb_block_given_p()) {
        return rb_ensure(rb_yield, self, buffer_free, self);
    }

    return self;
}

/*
 * call-seq: initialize_copy(other)
 * @return [self]
 * DO NOT CALL THIS METHOD.
 */
static VALUE
buffer_initialize_copy(VALUE self, VALUE other)
{
    AbstractMemory* src;
    Buffer* dst;
    
    Data_Get_Struct(self, Buffer, dst);
    src = rbffi_AbstractMemory_Cast(other, BufferClass);
    if ((dst->memory.flags & MEM_EMBED) == 0 && dst->data.storage != NULL) {
        xfree(dst->data.storage);
    }
    dst->data.storage = xmalloc(src->size + 7);
    if (dst->data.storage == NULL) {
        rb_raise(rb_eNoMemError, "failed to allocate memory size=%lu bytes", src->size);
        return Qnil;
    }
    
    dst->memory.address = (void *) (((uintptr_t) dst->data.storage + 0x7) & (uintptr_t) ~0x7UL);
    dst->memory.size = src->size;
    dst->memory.typeSize = src->typeSize;
    
    /* finally, copy the actual buffer contents */
    memcpy(dst->memory.address, src->address, src->size);

    return self;
}

static VALUE
buffer_alloc_inout(int argc, VALUE* argv, VALUE klass)
{
    return buffer_initialize(argc, argv, buffer_allocate(klass));
}

static VALUE
slice(VALUE self, long offset, long len)
{
    Buffer* ptr;
    Buffer* result;
    VALUE obj = Qnil;
    
    Data_Get_Struct(self, Buffer, ptr);
    checkBounds(&ptr->memory, offset, len);

    obj = Data_Make_Struct(BufferClass, Buffer, buffer_mark, -1, result);
    result->memory.address = ptr->memory.address + offset;
    result->memory.size = len;
    result->memory.flags = ptr->memory.flags;
    result->memory.typeSize = ptr->memory.typeSize;
    result->data.rbParent = self;

    return obj;
}

/*
 * call-seq: + offset
 * @param [Numeric] offset
 * @return [Buffer] a new instance of Buffer pointing from offset until end of previous buffer.
 * Add a Buffer with an offset
 */
static VALUE
buffer_plus(VALUE self, VALUE rbOffset)
{
    Buffer* ptr;
    long offset = NUM2LONG(rbOffset);

    Data_Get_Struct(self, Buffer, ptr);

    return slice(self, offset, ptr->memory.size - offset);
}

/*
 * call-seq: slice(offset, length)
 * @param [Numeric] offset
 * @param [Numeric] length
 * @return [Buffer] a new instance of Buffer
 * Slice an existing Buffer.
 */
static VALUE
buffer_slice(VALUE self, VALUE rbOffset, VALUE rbLength)
{
    return slice(self, NUM2LONG(rbOffset), NUM2LONG(rbLength));
}

/*
 * call-seq: inspect
 * @return [String]
 * Inspect a Buffer.
 */
static VALUE
buffer_inspect(VALUE self)
{
    char tmp[100];
    Buffer* ptr;

    Data_Get_Struct(self, Buffer, ptr);

    snprintf(tmp, sizeof(tmp), "#<FFI:Buffer:%p address=%p size=%ld>", ptr, ptr->memory.address, ptr->memory.size);
    
    return rb_str_new2(tmp);
}


#if BYTE_ORDER == LITTLE_ENDIAN
# define SWAPPED_ORDER BIG_ENDIAN
#else
# define SWAPPED_ORDER LITTLE_ENDIAN
#endif

/*
 * Set or get endianness of Buffer.
 * @overload order
 *  @return [:big, :little]
 *  Get endianness of Buffer.
 * @overload order(order)
 *  @param [:big, :little, :network] order
 *  @return [self]
 *  Set endianness of Buffer (+:network+ is an alias for +:big+).
 */
static VALUE
buffer_order(int argc, VALUE* argv, VALUE self)
{
    Buffer* ptr;

    Data_Get_Struct(self, Buffer, ptr);
    if (argc == 0) {
        int order = (ptr->memory.flags & MEM_SWAP) == 0 ? BYTE_ORDER : SWAPPED_ORDER;
        return order == BIG_ENDIAN ? ID2SYM(rb_intern("big")) : ID2SYM(rb_intern("little"));
    } else {
        VALUE rbOrder = Qnil;
        int order = BYTE_ORDER;

        if (rb_scan_args(argc, argv, "1", &rbOrder) < 1) {
            rb_raise(rb_eArgError, "need byte order");
        }
        if (SYMBOL_P(rbOrder)) {
            ID id = SYM2ID(rbOrder);
            if (id == rb_intern("little")) {
                order = LITTLE_ENDIAN;

            } else if (id == rb_intern("big") || id == rb_intern("network")) {
                order = BIG_ENDIAN;
            }
        }
        if (order != BYTE_ORDER) {
            Buffer* p2;
            VALUE retval = slice(self, 0, ptr->memory.size);

            Data_Get_Struct(retval, Buffer, p2);
            p2->memory.flags |= MEM_SWAP;
            return retval;
        }

        return self;
    }
}

/* Only used to free the buffer if the yield in the initializer throws an exception */
static VALUE
buffer_free(VALUE self)
{
    Buffer* ptr;

    Data_Get_Struct(self, Buffer, ptr);
    if ((ptr->memory.flags & MEM_EMBED) == 0 && ptr->data.storage != NULL) {
        xfree(ptr->data.storage);
        ptr->data.storage = NULL;
    }

    return self;
}

static void
buffer_mark(Buffer* ptr)
{
    rb_gc_mark(ptr->data.rbParent);
}

void
rbffi_Buffer_Init(VALUE moduleFFI)
{
    VALUE ffi_AbstractMemory =  rbffi_AbstractMemoryClass;

    /*
     * Document-class: FFI::Buffer < FFI::AbstractMemory
     *
     * A Buffer is a function argument type. It should be use with functions playing with C arrays.
     */
    BufferClass = rb_define_class_under(moduleFFI, "Buffer", ffi_AbstractMemory);

    /*
     * Document-variable: FFI::Buffer
     */
    rb_global_variable(&BufferClass);
    rb_define_alloc_func(BufferClass, buffer_allocate);

    /*
     * Document-method: alloc_inout
     * call-seq: alloc_inout(*args)
     * Create a new Buffer for in and out arguments (alias : <i>new_inout</i>).
     */
    rb_define_singleton_method(BufferClass, "alloc_inout", buffer_alloc_inout, -1);
    /*
     * Document-method: alloc_out
     * call-seq: alloc_out(*args)
     * Create a new Buffer for out arguments (alias : <i>new_out</i>).
     */
    rb_define_singleton_method(BufferClass, "alloc_out", buffer_alloc_inout, -1);
    /*
     * Document-method: alloc_in
     * call-seq: alloc_in(*args)
     * Create a new Buffer for in arguments (alias : <i>new_in</i>).
     */
    rb_define_singleton_method(BufferClass, "alloc_in", buffer_alloc_inout, -1);
    rb_define_alias(rb_singleton_class(BufferClass), "new_in", "alloc_in");
    rb_define_alias(rb_singleton_class(BufferClass), "new_out", "alloc_out");
    rb_define_alias(rb_singleton_class(BufferClass), "new_inout", "alloc_inout");
    
    rb_define_method(BufferClass, "initialize", buffer_initialize, -1);
    rb_define_method(BufferClass, "initialize_copy", buffer_initialize_copy, 1);
    rb_define_method(BufferClass, "order", buffer_order, -1);
    rb_define_method(BufferClass, "inspect", buffer_inspect, 0);
    rb_define_alias(BufferClass, "length", "total");
    rb_define_method(BufferClass, "+", buffer_plus, 1);
    rb_define_method(BufferClass, "slice", buffer_slice, 2);
}

