package git

/*
#include <git2.h>
#include <string.h>

int _go_git_writestream_write(git_writestream *stream, const char *buffer, size_t len);
void _go_git_writestream_free(git_writestream *stream);
*/
import "C"
import (
	"io"
	"reflect"
	"runtime"
	"unsafe"
)

type Blob struct {
	Object
	cast_ptr *C.git_blob
}

func (v *Blob) Size() int64 {
	ret := int64(C.git_blob_rawsize(v.cast_ptr))
	runtime.KeepAlive(v)
	return ret
}

func (v *Blob) Contents() []byte {
	size := C.int(C.git_blob_rawsize(v.cast_ptr))
	buffer := unsafe.Pointer(C.git_blob_rawcontent(v.cast_ptr))

	goBytes := C.GoBytes(buffer, size)
	runtime.KeepAlive(v)

	return goBytes
}

func (repo *Repository) CreateBlobFromBuffer(data []byte) (*Oid, error) {
	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	var id C.git_oid
	var size C.size_t

	// Go 1.6 added some increased checking of passing pointer to
	// C, but its check depends on its expectations of waht we
	// pass to the C function, so unless we take the address of
	// its contents at the call site itself, it can fail when
	// 'data' is a slice of a slice.
	//
	// When we're given an empty slice, create a dummy one where 0
	// isn't out of bounds.
	if len(data) > 0 {
		size = C.size_t(len(data))
	} else {
		data = []byte{0}
		size = C.size_t(0)
	}

	ecode := C.git_blob_create_frombuffer(&id, repo.ptr, unsafe.Pointer(&data[0]), size)
	runtime.KeepAlive(repo)
	if ecode < 0 {
		return nil, MakeGitError(ecode)
	}
	return newOidFromC(&id), nil
}

type BlobChunkCallback func(maxLen int) ([]byte, error)

type BlobCallbackData struct {
	Callback BlobChunkCallback
	Error    error
}

//export blobChunkCb
func blobChunkCb(buffer *C.char, maxLen C.size_t, handle unsafe.Pointer) int {
	payload := pointerHandles.Get(handle)
	data, ok := payload.(*BlobCallbackData)
	if !ok {
		panic("could not retrieve blob callback data")
	}

	goBuf, err := data.Callback(int(maxLen))
	if err == io.EOF {
		return 0
	} else if err != nil {
		data.Error = err
		return -1
	}
	C.memcpy(unsafe.Pointer(buffer), unsafe.Pointer(&goBuf[0]), C.size_t(len(goBuf)))
	return len(goBuf)
}

func (repo *Repository) CreateFromStream(hintPath string) (*BlobWriteStream, error) {
	var chintPath *C.char = nil
	var stream *C.git_writestream

	if len(hintPath) > 0 {
		chintPath = C.CString(hintPath)
		defer C.free(unsafe.Pointer(chintPath))
	}

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	ecode := C.git_blob_create_fromstream(&stream, repo.ptr, chintPath)
	if ecode < 0 {
		return nil, MakeGitError(ecode)
	}

	return newBlobWriteStreamFromC(stream, repo), nil
}

type BlobWriteStream struct {
	ptr  *C.git_writestream
	repo *Repository
}

func newBlobWriteStreamFromC(ptr *C.git_writestream, repo *Repository) *BlobWriteStream {
	stream := &BlobWriteStream{
		ptr:  ptr,
		repo: repo,
	}

	runtime.SetFinalizer(stream, (*BlobWriteStream).Free)
	return stream
}

// Implement io.Writer
func (stream *BlobWriteStream) Write(p []byte) (int, error) {
	header := (*reflect.SliceHeader)(unsafe.Pointer(&p))
	ptr := (*C.char)(unsafe.Pointer(header.Data))
	size := C.size_t(header.Len)

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	ecode := C._go_git_writestream_write(stream.ptr, ptr, size)
	runtime.KeepAlive(stream)
	if ecode < 0 {
		return 0, MakeGitError(ecode)
	}

	return len(p), nil
}

func (stream *BlobWriteStream) Free() {
	runtime.SetFinalizer(stream, nil)
	C._go_git_writestream_free(stream.ptr)
}

func (stream *BlobWriteStream) Commit() (*Oid, error) {
	oid := C.git_oid{}

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	ecode := C.git_blob_create_fromstream_commit(&oid, stream.ptr)
	runtime.KeepAlive(stream)
	if ecode < 0 {
		return nil, MakeGitError(ecode)
	}

	return newOidFromC(&oid), nil
}
