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 {
	gitObject
	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.gitObject.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.gitObject.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
}
