package git

/*
#include <git2.h>

extern int _go_git_tag_foreach(git_repository *repo, void *payload);
*/
import "C"
import (
	"runtime"
	"unsafe"
)

// Tag
type Tag struct {
	Object
	cast_ptr *C.git_tag
}

func (t Tag) Message() string {
	return C.GoString(C.git_tag_message(t.cast_ptr))
}

func (t Tag) Name() string {
	return C.GoString(C.git_tag_name(t.cast_ptr))
}

func (t Tag) Tagger() *Signature {
	cast_ptr := C.git_tag_tagger(t.cast_ptr)
	return newSignatureFromC(cast_ptr)
}

func (t Tag) Target() *Object {
	var ptr *C.git_object
	ret := C.git_tag_target(&ptr, t.cast_ptr)

	if ret != 0 {
		return nil
	}

	return allocObject(ptr, t.repo)
}

func (t Tag) TargetId() *Oid {
	return newOidFromC(C.git_tag_target_id(t.cast_ptr))
}

func (t Tag) TargetType() ObjectType {
	return ObjectType(C.git_tag_target_type(t.cast_ptr))
}

type TagsCollection struct {
	repo *Repository
}

func (c *TagsCollection) Create(
	name string, commit *Commit, tagger *Signature, message string) (*Oid, error) {

	oid := new(Oid)

	cname := C.CString(name)
	defer C.free(unsafe.Pointer(cname))

	cmessage := C.CString(message)
	defer C.free(unsafe.Pointer(cmessage))

	taggerSig, err := tagger.toC()
	if err != nil {
		return nil, err
	}
	defer C.git_signature_free(taggerSig)

	ctarget := commit.ptr

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	ret := C.git_tag_create(oid.toC(), c.repo.ptr, cname, ctarget, taggerSig, cmessage, 0)
	if ret < 0 {
		return nil, MakeGitError(ret)
	}

	return oid, nil
}

// CreateLightweight creates a new lightweight tag pointing to a commit
// and returns the id of the target object.
//
// The name of the tag is validated for consistency (see git_tag_create() for the rules
// https://libgit2.github.com/libgit2/#HEAD/group/tag/git_tag_create) and should
// not conflict with an already existing tag name.
//
// If force is true and a reference already exists with the given name, it'll be replaced.
//
// The created tag is a simple reference and can be queried using
// repo.References.Lookup("refs/tags/<name>"). The name of the tag (eg "v1.0.0")
// is queried with ref.Shorthand().
func (c *TagsCollection) CreateLightweight(name string, commit *Commit, force bool) (*Oid, error) {

	oid := new(Oid)

	cname := C.CString(name)
	defer C.free(unsafe.Pointer(cname))

	ctarget := commit.ptr

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	err := C.git_tag_create_lightweight(oid.toC(), c.repo.ptr, cname, ctarget, cbool(force))
	if err < 0 {
		return nil, MakeGitError(err)
	}

	return oid, nil
}

// List returns the names of all the tags in the repository,
// eg: ["v1.0.1", "v2.0.0"].
func (c *TagsCollection) List() ([]string, error) {
	var strC C.git_strarray

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	ecode := C.git_tag_list(&strC, c.repo.ptr)
	if ecode < 0 {
		return nil, MakeGitError(ecode)
	}
	defer C.git_strarray_free(&strC)

	tags := makeStringsFromCStrings(strC.strings, int(strC.count))
	return tags, nil
}

// ListWithMatch returns the names of all the tags in the repository
// that match a given pattern.
//
// The pattern is a standard fnmatch(3) pattern http://man7.org/linux/man-pages/man3/fnmatch.3.html
func (c *TagsCollection) ListWithMatch(pattern string) ([]string, error) {
	var strC C.git_strarray

	patternC := C.CString(pattern)
	defer C.free(unsafe.Pointer(patternC))

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	ecode := C.git_tag_list_match(&strC, patternC, c.repo.ptr)
	if ecode < 0 {
		return nil, MakeGitError(ecode)
	}
	defer C.git_strarray_free(&strC)

	tags := makeStringsFromCStrings(strC.strings, int(strC.count))
	return tags, nil
}

// TagForeachCallback is called for each tag in the repository.
//
// The name is the full ref name eg: "refs/tags/v1.0.0".
//
// Note that the callback is called for lightweight tags as well,
// so repo.LookupTag() will return an error for these tags. Use
// repo.References.Lookup() instead.
type TagForeachCallback func(name string, id *Oid) error
type tagForeachData struct {
	callback TagForeachCallback
	err      error
}

//export gitTagForeachCb
func gitTagForeachCb(name *C.char, id *C.git_oid, handle unsafe.Pointer) int {
	payload := pointerHandles.Get(handle)
	data, ok := payload.(*tagForeachData)
	if !ok {
		panic("could not retrieve tag foreach CB handle")
	}

	err := data.callback(C.GoString(name), newOidFromC(id))
	if err != nil {
		data.err = err
		return C.GIT_EUSER
	}

	return 0
}

// Foreach calls the callback for each tag in the repository.
func (c *TagsCollection) Foreach(callback TagForeachCallback) error {
	data := tagForeachData{
		callback: callback,
		err:      nil,
	}

	handle := pointerHandles.Track(&data)
	defer pointerHandles.Untrack(handle)

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	err := C._go_git_tag_foreach(c.repo.ptr, handle)
	if err == C.GIT_EUSER {
		return data.err
	}
	if err < 0 {
		return MakeGitError(err)
	}

	return nil
}
