package git

/*
#include <git2.h>

extern void _go_git_populate_remote_cb(git_clone_options *opts);
*/
import "C"
import (
	"runtime"
	"unsafe"
)

type RemoteCreateCallback func(repo *Repository, name, url string) (*Remote, ErrorCode)

type CloneOptions struct {
	*CheckoutOpts
	*FetchOptions
	Bare                 bool
	CheckoutBranch       string
	RemoteCreateCallback RemoteCreateCallback
}

func Clone(url string, path string, options *CloneOptions) (*Repository, error) {
	curl := C.CString(url)
	defer C.free(unsafe.Pointer(curl))

	cpath := C.CString(path)
	defer C.free(unsafe.Pointer(cpath))

	copts := (*C.git_clone_options)(C.calloc(1, C.size_t(unsafe.Sizeof(C.git_clone_options{}))))
	populateCloneOptions(copts, options)
	defer freeCloneOptions(copts)

	if len(options.CheckoutBranch) != 0 {
		copts.checkout_branch = C.CString(options.CheckoutBranch)
	}

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	var ptr *C.git_repository
	ret := C.git_clone(&ptr, curl, cpath, copts)
	freeCheckoutOpts(&copts.checkout_opts)

	if ret < 0 {
		return nil, MakeGitError(ret)
	}

	return newRepositoryFromC(ptr), nil
}

//export remoteCreateCallback
func remoteCreateCallback(cremote unsafe.Pointer, crepo unsafe.Pointer, cname, curl *C.char, payload unsafe.Pointer) C.int {
	name := C.GoString(cname)
	url := C.GoString(curl)
	repo := newRepositoryFromC((*C.git_repository)(crepo))
	// We don't own this repository, so make sure we don't try to free it
	runtime.SetFinalizer(repo, nil)

	if opts, ok := pointerHandles.Get(payload).(CloneOptions); ok {
		remote, err := opts.RemoteCreateCallback(repo, name, url)
		// clear finalizer as the calling C function will
		// free the remote itself
		runtime.SetFinalizer(remote, nil)

		if err == ErrOk && remote != nil {
			cptr := (**C.git_remote)(cremote)
			*cptr = remote.ptr
		} else if err == ErrOk && remote == nil {
			panic("no remote created by callback")
		}

		return C.int(err)
	} else {
		panic("invalid remote create callback")
	}
}

func populateCloneOptions(ptr *C.git_clone_options, opts *CloneOptions) {
	C.git_clone_init_options(ptr, C.GIT_CLONE_OPTIONS_VERSION)

	if opts == nil {
		return
	}
	populateCheckoutOpts(&ptr.checkout_opts, opts.CheckoutOpts)
	populateFetchOptions(&ptr.fetch_opts, opts.FetchOptions)
	ptr.bare = cbool(opts.Bare)

	if opts.RemoteCreateCallback != nil {
		// Go v1.1 does not allow to assign a C function pointer
		C._go_git_populate_remote_cb(ptr)
		ptr.remote_cb_payload = pointerHandles.Track(*opts)
	}
}

func freeCloneOptions(ptr *C.git_clone_options) {
	if ptr == nil {
		return
	}

	freeCheckoutOpts(&ptr.checkout_opts)

	if ptr.remote_cb_payload != nil {
		pointerHandles.Untrack(ptr.remote_cb_payload)
	}

	C.free(unsafe.Pointer(ptr.checkout_branch))
	C.free(unsafe.Pointer(ptr))
}
